Create VCN (Coming soon)
🚧 Coming soon — this endpoint is not yet available in Sandbox or Production. The documentation is published so you can prepare your integration; we'll announce in the changelog when it goes live.
Issues a virtual card (VCN) for a hotel or air booking.
Authentication: in addition to the API key/secret (which identifies the client), this endpoint requires mTLS at the transport layer.
Returns PAN, CVV and expiration synchronously. The CVV is never persisted.
Send hotelBooking when type is HOTEL and flightBooking when it is AIR — never both at once.
Resending with the same Idempotency-Key returns the same VCN; reusing the key with a different payload returns 409.
curl -X POST "https://api-sandbox.contasimples.com/credit-cards/v1/vcns" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: example_string" \
-H "X-Origin: ACME_TRAVEL" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"type": "HOTEL",
"amount": {
"rate": 1200,
"taxes": 280,
"currency": "BRL"
},
"hotelBooking": {
"checkIn": "2026-06-01",
"checkOut": "2026-06-05",
"guests": 1,
"rooms": 1,
"hotelName": "Ibis Styles Palmas",
"confirmationId": "000001"
},
"customFields": [
{
"key": "CENTRO DE CUSTO",
"value": "Engenharia"
}
],
"bookingId": "ACME-RES-998877"
}'
import requests
import json
url = "https://api-sandbox.contasimples.com/credit-cards/v1/vcns"
headers = {
"Content-Type": "application/json",
"Idempotency-Key": "example_string",
"X-Origin": "ACME_TRAVEL",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"type": "HOTEL",
"amount": {
"rate": 1200,
"taxes": 280,
"currency": "BRL"
},
"hotelBooking": {
"checkIn": "2026-06-01",
"checkOut": "2026-06-05",
"guests": 1,
"rooms": 1,
"hotelName": "Ibis Styles Palmas",
"confirmationId": "000001"
},
"customFields": [
{
"key": "CENTRO DE CUSTO",
"value": "Engenharia"
}
],
"bookingId": "ACME-RES-998877"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://api-sandbox.contasimples.com/credit-cards/v1/vcns", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "example_string",
"X-Origin": "ACME_TRAVEL",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"type": "HOTEL",
"amount": {
"rate": 1200,
"taxes": 280,
"currency": "BRL"
},
"hotelBooking": {
"checkIn": "2026-06-01",
"checkOut": "2026-06-05",
"guests": 1,
"rooms": 1,
"hotelName": "Ibis Styles Palmas",
"confirmationId": "000001"
},
"customFields": [
{
"key": "CENTRO DE CUSTO",
"value": "Engenharia"
}
],
"bookingId": "ACME-RES-998877"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"type": "HOTEL",
"amount": {
"rate": 1200,
"taxes": 280,
"currency": "BRL"
},
"hotelBooking": {
"checkIn": "2026-06-01",
"checkOut": "2026-06-05",
"guests": 1,
"rooms": 1,
"hotelName": "Ibis Styles Palmas",
"confirmationId": "000001"
},
"customFields": [
{
"key": "CENTRO DE CUSTO",
"value": "Engenharia"
}
],
"bookingId": "ACME-RES-998877"
}`)
req, err := http.NewRequest("POST", "https://api-sandbox.contasimples.com/credit-cards/v1/vcns", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "example_string")
req.Header.Set("X-Origin", "ACME_TRAVEL")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api-sandbox.contasimples.com/credit-cards/v1/vcns')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Idempotency-Key'] = 'example_string'
request['X-Origin'] = 'ACME_TRAVEL'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"type": "HOTEL",
"amount": {
"rate": 1200,
"taxes": 280,
"currency": "BRL"
},
"hotelBooking": {
"checkIn": "2026-06-01",
"checkOut": "2026-06-05",
"guests": 1,
"rooms": 1,
"hotelName": "Ibis Styles Palmas",
"confirmationId": "000001"
},
"customFields": [
{
"key": "CENTRO DE CUSTO",
"value": "Engenharia"
}
],
"bookingId": "ACME-RES-998877"
}'
response = http.request(request)
puts response.body
{
"vcnId": "21624502",
"bookingId": "ACME-AIR-554433",
"type": "AIR",
"card": {
"pan": "4656350026056026",
"cvv": "411",
"expirationDate": "06/31",
"holderName": "EXAMPLE COMPANY LTD"
},
"controls": {
"spendLimit": {
"value": 101,
"currency": "BRL"
},
"maxTransactions": 2,
"validity": {
"start": "2026-06-09",
"end": "2026-06-10"
},
"merchantCategory": "AIR"
},
"status": "ACTIVE",
"createdAt": "2026-06-09T15:55:10Z"
}
{
"error": "Bad Request",
"message": "One or more request parameters are invalid.",
"code": 400,
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"details": [
"The example field must have a value between 5 and 100.",
"Dates must be in YYYY-MM-DD format."
]
}
{
"error": "Unauthorized",
"message": "Invalid or expired access token.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 401
}
{
"error": "Forbidden",
"message": "You do not have permission to perform this operation.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 403
}
{
"error": "Conflict",
"message": "A supplier with the same name already exists for this company.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 409
}
{
"error": "Unprocessable Entity",
"message": "The provided category does not exist or does not belong to the company.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 422
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred while processing the request.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 500
}
/credit-cards/v1/vcns
Target server for requests. Edit to use your own host.
Bearer token from OAuth 2.0 client credentials. Format: Bearer {token}
Bearer {token}The media type of the request body
Dedupe — use the booking identifier (bookingId). A stable string, unique per booking.
Identifies the originating OBT. Assigned by Conta Simples during onboarding.
Product type. Defines which booking block is required (HOTEL → hotelBooking, AIR → flightBooking).
Booking identifier on the OBT side. Basis for idempotency.
Decimal values (e.g. 100.00), in the currency given by currency. The card limit equals rate + taxes.
Client governance fields (e.g. cost center, requester). They show up on the card statement/report and are available for reconciliation.
Additional extension fields (key/value), stored only at Conta Simples. Use only for data not covered by hotelBooking/flightBooking or customFields.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Bearer token from OAuth 2.0 client credentials. Format: Bearer {token}
Headers
Dedupe — use the booking identifier (bookingId). A stable string, unique per booking.
Identifies the originating OBT. Assigned by Conta Simples during onboarding.
ACME_TRAVELBody
Product type. Defines which booking block is required (HOTEL → hotelBooking, AIR → flightBooking).
HOTELAIRBooking identifier on the OBT side. Basis for idempotency.
Decimal values (e.g. 100.00), in the currency given by currency. The card limit equals rate + taxes.
Check-in date, ISO format (YYYY-MM-DD).
Check-out date, ISO format (YYYY-MM-DD).
Number of guests. Affects the limit margin.
Number of rooms. Affects the number of allowed authorizations.
Lead guest first name.
Lead guest last name.
Hotel name.
Booking confirmation ID / locator.
Departure date, ISO format (YYYY-MM-DD).
Return date. Absent/null = one-way.
Number of passengers.
Lead passenger first name.
Lead passenger last name.
Booking locator (PNR).
Issuing carrier (IATA code, e.g. JJ).
Ticket number.
Client governance fields (e.g. cost center, requester). They show up on the card statement/report and are available for reconciliation.
Additional extension fields (key/value), stored only at Conta Simples. Use only for data not covered by hotelBooking/flightBooking or customFields.
Responses
HOTELAIRCard number (PAN). Must not be logged.
Security code (CVV). Never persisted.
Card expiration in MM/YY format (e.g. 06/31 = June 2031).
Cardholder name.
Merchant category (MCC) locked on the card: LODG (lodging) when type=HOTEL, AIR (airlines) when type=AIR.
LODGAIRACTIVECANCELLEDEXPIREDShort error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.
Short error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.
Short error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.
Short error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.
Short error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.
Short error type (e.g. Bad Request, Not Found).
Brief error message for API clients.
HTTP status code for the error (matches the response status).
Optional. For 400 errors, may be a single string or an array of strings with each validation failure.