Create VCN (Coming soon)
π§ Coming soon β this endpoint is not available in Sandbox or Production yet. The documentation is published so you can prepare your integration; we will announce it in the changelog when it goes live.
Issues a virtual card (VCN) tied to a lodging booking (HOTEL), an air booking (AERIAL) or a use you define (CUSTOM β e.g. one card per supplier). PAN, CVV and expiration are returned synchronously.
Send exactly one block, the one matching your type β hotelBooking, flightBooking or reference β carrying the idempotency key inside it (reservationId, recordLocator β the PNR, Passenger Name Record β or reference.id). For booking types you send the cost (amount) and the card ceiling is derived from it; for CUSTOM you send the ceiling (limit) and no amount. Each field's rules are documented on the field itself, below; each error's behavior, under Responses.
Store the vcnId from the response: it addresses the top-up in Update VCN and the card-data retrieval in Reveal VCN card data.
curl -X POST "https://api-sandbox.contasimples.com/credit-cards/v1/vcns" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": {
"name": "Agente Exemplo",
"email": "agente@exemplo.test",
"phone": "+5511900000000"
}
}'
import requests
import json
url = "https://api-sandbox.contasimples.com/credit-cards/v1/vcns"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": {
"name": "Agente Exemplo",
"email": "agente@exemplo.test",
"phone": "+5511900000000"
}
}
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",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": {
"name": "Agente Exemplo",
"email": "agente@exemplo.test",
"phone": "+5511900000000"
}
})
});
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": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": {
"name": "Agente Exemplo",
"email": "agente@exemplo.test",
"phone": "+5511900000000"
}
}`)
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("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['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": {
"name": "Agente Exemplo",
"email": "agente@exemplo.test",
"phone": "+5511900000000"
}
}'
response = http.request(request)
puts response.body
{
"vcnId": "01JQ8ZK7X4M8N2P5R6T7V8W9XY",
"type": "HOTEL",
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2026-09-15",
"checkOut": "2026-09-18",
"propertyId": "PROP-000123",
"hotelName": "Ibis Styles Palmas",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"status": "ACTIVE",
"startDate": "2026-08-21",
"endDate": "2026-10-08",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"limit": {
"value": 1622.5,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"card": {
"pan": "4111111111111111",
"cvv": "123",
"expirationDate": "06/2031"
}
}
{
"vcnId": "01JQ8ZM3T6R9V2X5Y7Z8A9B0CD",
"type": "AERIAL",
"flightBooking": {
"recordLocator": "ABC123",
"passengerName": "Carla",
"passengerSurname": "Nogueira",
"issuingCarrier": "JJ",
"issueDate": "2026-08-25",
"numOfLegs": 2,
"legsDescription": "GRU-BSB-GRU",
"domesticIndicator": "DOMESTIC",
"finalDestinationCity": "BSB",
"tripLegs": [
{
"legNumber": 1,
"origin": "GRU",
"destination": "BSB",
"departureDate": "2026-09-10"
},
{
"legNumber": 2,
"origin": "BSB",
"destination": "GRU",
"departureDate": "2026-09-14"
}
]
},
"status": "ACTIVE",
"startDate": "2026-08-21",
"endDate": "2026-08-22",
"amount": {
"rate": 890,
"taxes": 112.4,
"fees": 0,
"currency": "BRL"
},
"limit": {
"value": 1002.4,
"currency": "BRL"
},
"maxPurchaseQuantity": 2,
"card": {
"pan": "4111111111111111",
"cvv": "456",
"expirationDate": "06/2031"
}
}
{
"vcnId": "01JQ8ZP4C7D9F1G3H5J7K9L2MN",
"type": "CUSTOM",
"reference": {
"id": "SUP-000123"
},
"status": "ACTIVE",
"startDate": "2026-08-21",
"endDate": "2026-10-27",
"limit": {
"value": 0.01,
"currency": "BRL"
},
"maxPurchaseQuantity": 10000,
"card": {
"pan": "4111111111111111",
"cvv": "789",
"expirationDate": "06/2031"
}
}
{
"code": "bad-request-exception",
"message": "Event failed validation",
"errors": [
{
"field": "body.hotelBooking",
"message": "hotelBooking is required for a lodging booking"
}
]
}
{
"code": "bad-request-exception",
"message": "Event failed validation",
"errors": [
{
"field": "body.hotelBooking",
"message": "hotelBooking is only accepted for a lodging booking"
}
]
}
{
"code": "bad-request-exception",
"message": "Event failed validation",
"errors": [
{
"field": "body.amount.rate",
"message": "amount.rate must have at most 2 decimal places"
}
]
}
{
"code": "active-funding-card-not-found",
"message": "There is no active funding card. Check the request or provision the company for this combination, then retry."
}
{
"code": "invalid-vcn-request",
"message": "Unable to issue a VCN for this request: validity window must end after it starts"
}
{
"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
}
{
"code": "vcn-already-issued",
"message": "An active VCN already exists for this key."
}
{
"code": "internal-exception",
"message": "Aconteceu um erro"
}
/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 TOKENThe media type of the request body
What the card is tied to. Defines the required block (HOTEL β hotelBooking, AERIAL β flightBooking, CUSTOM β reference) and how the ceiling is born: derived from amount for booking types, sent in limit for CUSTOM.
Booking cost, as decimal with at most 2 places (e.g. 1250.00). Required for `HOTEL` and `AERIAL`; forbidden for `CUSTOM`, which declares the ceiling directly in limit. The sum rate + taxes + fees must be greater than zero and defines the card's derived ceiling. A value with more than 2 decimal places is rejected with 400 β it is not rounded.
Card spending ceiling. Required for `CUSTOM`; forbidden for HOTEL/AERIAL, where the ceiling is derived from amount.
Start of the usage window, YYYY-MM-DD, accepted for all three types. Omitted, the window opens at the moment of issuance. Sent, it cannot fall on a day before the issuance day, and endDate must come after it β otherwise, 400 invalid-vcn-request.
End of the usage window, YYYY-MM-DD, accepted for all three types. When sent, it takes precedence over the derived validity (HOTEL = checkOut + 20 days Β· AERIAL = issuance + 1 day Β· CUSTOM = issuance + 60 days). Cap: 365 days from issuance β counted from issuance even when you send startDate, so postponing the start does not extend the cap. Beyond that, 400 invalid-vcn-request.
Maximum number of authorizations on the card, up to 100000. Overrides the type default (AERIAL 2 Β· HOTEL 3 Β· CUSTOM 10000).
Lodging data. Required when `type` is `HOTEL` and forbidden for other types.
Air booking data. Required when `type` is `AERIAL` and forbidden for other types.
What the CUSTOM card is tied to, defined by you (a supplier, a contract, a payable). Required when `type` is `CUSTOM` and forbidden for other types.
Client governance fields. If sent, it must have at least 1 item.
Who requested the issuance, for auditing. email and phone are for internal use and are not shared.
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
Body
What the card is tied to. Defines the required block (HOTEL β hotelBooking, AERIAL β flightBooking, CUSTOM β reference) and how the ceiling is born: derived from amount for booking types, sent in limit for CUSTOM.
HOTELAERIALCUSTOMBooking cost, as decimal with at most 2 places (e.g. 1250.00). Required for HOTEL and AERIAL; forbidden for CUSTOM, which declares the ceiling directly in limit. The sum rate + taxes + fees must be greater than zero and defines the card's derived ceiling. A value with more than 2 decimal places is rejected with 400 β it is not rounded.
Card spending ceiling. Required for CUSTOM; forbidden for HOTEL/AERIAL, where the ceiling is derived from amount.
Start of the usage window, YYYY-MM-DD, accepted for all three types. Omitted, the window opens at the moment of issuance. Sent, it cannot fall on a day before the issuance day, and endDate must come after it β otherwise, 400 invalid-vcn-request.
2026-09-10End of the usage window, YYYY-MM-DD, accepted for all three types. When sent, it takes precedence over the derived validity (HOTEL = checkOut + 20 days Β· AERIAL = issuance + 1 day Β· CUSTOM = issuance + 60 days). Cap: 365 days from issuance β counted from issuance even when you send startDate, so postponing the start does not extend the cap. Beyond that, 400 invalid-vcn-request.
2026-10-27Maximum number of authorizations on the card, up to 100000. Overrides the type default (AERIAL 2 Β· HOTEL 3 Β· CUSTOM 10000).
3Lodging data. Required when type is HOTEL and forbidden for other types.
Air booking data. Required when type is AERIAL and forbidden for other types.
What the CUSTOM card is tied to, defined by you (a supplier, a contract, a payable). Required when type is CUSTOM and forbidden for other types.
Client governance fields. If sent, it must have at least 1 item.
Who requested the issuance, for auditing. email and phone are for internal use and are not shared.