Create VCN
Use the Sandbox to prepare your integration and validate authentication and the contract.
Issues a virtual card (VCN) for a lodging booking (HOTEL), an air booking (AERIAL) or a use you define (CUSTOM, e.g. one card per supplier). PAN, CVV and expiration come back right away.
Before you call
- Send the identifier for your
type, which is also the idempotency key:hotelBooking.reservationId,flightBooking.recordLocatoror, forCUSTOM,reference. - For booking types, send the cost in
amount; forCUSTOM, send the ceiling inlimit. - Dates are calendar days in Brasília time, and
endDateis inclusive. - Store the
vcnIdfrom the201with your key: it addresses Get VCN, Update VCN, Reveal VCN card data and Cancel VCN, and no error returns it.
Security
The 201 carries PAN and CVV in clear text and comes with Cache-Control: no-store and Pragma: no-cache. Do not log or cache the card block.
Errors
400 bad-request-exception— the body is malformed;errors[]points at each field. Includes the identifier of another type (e.g.referenceoutsideCUSTOM) and anendDateequal to or earlier thanstartDatewhen both dates are sent.400 invalid-vcn-request— the dates or amounts do not form a valid window or ceiling; the reason comes inmessage. See Usage window.400 active-funding-card-not-found— thetypeis not enabled for your credential. Contact Conta Simples.400 bad-request-exception— missing or malformedX-Partner-Id(fieldheaders.x-partner-id). See Platform identification.403 caller-not-authorized— theX-Partner-Idpartner is not bound to your credential (details.reasonPARTNER_NOT_BOUND), or the credential lacks the route scope (details.requiredScope). See Platform identification.409 vcn-already-issued— a live VCN already exists for this key. ForCUSTOM, top it up with Update VCN. See Idempotency and reissuance.500 internal-exception— internal error, including a provider failure or a timeout. Do not retry automatically: the card may have been issued. Contact support with the time, therequestIdand the key.
Rules
Usage window · Idempotency and reissuance · Ceiling and top-up · Request body
curl -X POST "https://api-sandbox.contasimples.com/credit-cards/v1/vcns" \
-H "Content-Type: application/json" \
-H "X-Partner-Id: ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XY" \
-H "Signature-Input: example_string" \
-H "Signature: example_string" \
-H "Content-Digest: example_string" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": "agente@exemplo.test"
}'
import requests
import json
url = "https://api-sandbox.contasimples.com/credit-cards/v1/vcns"
headers = {
"Content-Type": "application/json",
"X-Partner-Id": "ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XY",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": "agente@exemplo.test"
}
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",
"X-Partner-Id": "ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XY",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": "agente@exemplo.test"
})
});
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"
},
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": "agente@exemplo.test"
}`)
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("X-Partner-Id", "ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XY")
req.Header.Set("Signature-Input", "example_string")
req.Header.Set("Signature", "example_string")
req.Header.Set("Content-Digest", "example_string")
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['X-Partner-Id'] = 'ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XY'
request['Signature-Input'] = 'example_string'
request['Signature'] = 'example_string'
request['Content-Digest'] = 'example_string'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"type": "HOTEL",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"customFields": [
{
"name": "costCenter",
"value": "CC-042",
"dataType": "string"
}
],
"requestor": "agente@exemplo.test"
}'
response = http.request(request)
puts response.body
{
"vcnId": "01JQ8ZK7X4M8N2P5R6T7V8W9XY",
"type": "HOTEL",
"reference": "ACME-RES-998877",
"hotelBooking": {
"reservationId": "ACME-RES-998877",
"checkIn": "2027-03-15",
"checkOut": "2027-03-18",
"propertyId": "PROP-000123",
"hotelName": "Hotel Exemplo",
"guests": [
{
"name": "Ana",
"surname": "Ribeiro"
},
{
"name": "Bruno",
"surname": "Alves"
}
],
"allowExtraCharges": true,
"extraChargesMargin": 150
},
"status": "ACTIVE",
"startDate": "2027-03-01",
"endDate": "2027-04-07",
"amount": {
"rate": 1250,
"taxes": 187.5,
"fees": 35,
"currency": "BRL"
},
"limit": {
"value": 1622.5,
"currency": "BRL"
},
"maxPurchaseQuantity": 3,
"spendLimitPeriod": "TOTAL",
"card": {
"pan": "4111111111111111",
"cvv": "123",
"expirationDate": "06/2031"
}
}
{
"vcnId": "01JQ8ZM3T6R9V2X5Y7Z8A9B0CD",
"type": "AERIAL",
"reference": "ABC123",
"flightBooking": {
"recordLocator": "ABC123",
"passengerName": "Carla",
"passengerSurname": "Nogueira",
"issuingCarrier": "ZZ",
"issueDate": "2027-03-01",
"numOfLegs": 2,
"legsDescription": "GRU-BSB-GRU",
"domesticIndicator": "DOMESTIC",
"finalDestinationCity": "BSB",
"tripLegs": [
{
"legNumber": 1,
"origin": "GRU",
"destination": "BSB",
"departureDate": "2027-03-10"
},
{
"legNumber": 2,
"origin": "BSB",
"destination": "GRU",
"departureDate": "2027-03-14"
}
]
},
"status": "ACTIVE",
"startDate": "2027-03-01",
"endDate": "2027-03-02",
"amount": {
"rate": 890,
"taxes": 112.4,
"fees": 0,
"currency": "BRL"
},
"limit": {
"value": 1002.4,
"currency": "BRL"
},
"maxPurchaseQuantity": 2,
"spendLimitPeriod": "TOTAL",
"card": {
"pan": "4111111111111111",
"cvv": "456",
"expirationDate": "06/2031"
}
}
{
"vcnId": "01JQ8ZP4C7D9F1G3H5J7K9J2MN",
"type": "CUSTOM",
"reference": "SUP-000123",
"status": "ACTIVE",
"startDate": "2027-03-01",
"endDate": "2027-05-07",
"limit": {
"value": 0.01,
"currency": "BRL"
},
"maxPurchaseQuantity": 10000,
"spendLimitPeriod": "TOTAL",
"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": "must be a non-negative amount with 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"
}
{
"code": "bad-request-exception",
"message": "Event failed validation",
"errors": [
{
"field": "body.endDate",
"message": "endDate must be later than startDate"
}
]
}
{
"code": "invalid-vcn-request",
"message": "Unable to issue a VCN for this request: end date must not exceed the funding card expiration"
}
{
"code": "bad-request-exception",
"message": "Event failed validation",
"errors": [
{
"field": "headers.x-partner-id",
"message": "x-partner-id must be a valid partner identifier"
}
]
}
{
"code": "unauthorized",
"message": "Authentication failed. Check the API token and the request signature",
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"code": "unauthorized",
"message": "Authentication failed. Check the API token and the request signature",
"details": {
"reason": "SIGNATURE_REQUIRED"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"code": "unauthorized",
"message": "Authentication failed. Check the API token and the request signature",
"details": {
"reason": "INVALID_SIGNATURE"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"code": "caller-not-authorized",
"message": "The request is not allowed for the current credentials",
"details": {
"requiredScope": "createVcn"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"code": "caller-not-authorized",
"message": "The request is not allowed for the current credentials",
"details": {
"reason": "PARTNER_NOT_BOUND"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"code": "vcn-already-issued",
"message": "An active VCN already exists for this key."
}
{
"code": "internal-exception",
"message": "An unexpected error occurred on the server"
}
/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
Identifier of the integrator platform (partner) the call is made through: ptn_ followed by a 26-character ULID. Conta Simples generates it and hands it to you at onboarding. See Platform identification.
What was signed and the signature parameters, in the RFC 9421 format. A credential with a public key must send it on every call, reads included, or the request is refused with 401. The signature covers the @method, @path, and @query components, and also content-digest when there is a body. created and alg are required, and created is valid for 300 seconds. The full format, with examples, is in Request Signing.
The signature of the base defined by RFC 9421, in base64, between : and under the same label used in Signature-Input, for example sig=:SGVsbG8gd29ybGQ=:. It always goes together with Signature-Input.
Hash of the request body in the RFC 9530 format, with sha-256 or sha-512, for example sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. It is required when the request has a body and the credential has a public key, and in that case Signature-Input must include the content-digest component.
What the card is tied to. Defines the required identifier (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, a decimal with up to 2 places (e.g. 1250.00), in BRL. Required for HOTEL and AERIAL, forbidden for CUSTOM. The sum rate + taxes + fees must be greater than zero and sets the ceiling.
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, as a Brasília day. Omitted, it is the issuance day. It cannot be earlier than today. See Usage window.
End of the usage window, YYYY-MM-DD, inclusive, as a Brasília day. Omitted, it is the type default: checkOut + 20 days for HOTEL, issuance + 1 day for AERIAL, issuance + 60 days for CUSTOM. At most 365 days from the issuance day. See Date limits.
Maximum number of authorizations on the card, up to 100000. Overrides the type default (AERIAL 2 · HOTEL 3 · CUSTOM 10000).
Ceiling period: TOTAL (default, the whole window), MONTHLY (renews every month) or DAILY (renews every day). Accepted for all three types. See Ceiling period.
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.
Identifier of what the CUSTOM card pays for, defined by you (e.g. the supplier id), as a 1-to-255-character string; it is the idempotency key, so do not use personal data. Only CUSTOM sends this field: for HOTEL and AERIAL, the key comes from hotelBooking.reservationId or flightBooking.recordLocator and returns in reference in the response, and sending reference gives 400 bad-request-exception with field body.reference. See Idempotency and reissuance.
Governance fields (e.g. cost center), 1 to 50 items. They show up in the transaction data on the card network, for reconciliation: never use personal data (CPF, passenger name, email, phone).
Who requests the issuance, update or cancellation, for auditing. Send a user's e-mail or, for an automated call, an identifier from your system. Free text, 1 to 100 characters.
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
Identifier of the integrator platform (partner) the call is made through: ptn_ followed by a 26-character ULID. Conta Simples generates it and hands it to you at onboarding. See Platform identification.
ptn_01JQ8ZK7X4M8N2P5R6T7V8W9XYWhat was signed and the signature parameters, in the RFC 9421 format. A credential with a public key must send it on every call, reads included, or the request is refused with 401. The signature covers the @method, @path, and @query components, and also content-digest when there is a body. created and alg are required, and created is valid for 300 seconds. The full format, with examples, is in Request Signing.
The signature of the base defined by RFC 9421, in base64, between : and under the same label used in Signature-Input, for example sig=:SGVsbG8gd29ybGQ=:. It always goes together with Signature-Input.
Hash of the request body in the RFC 9530 format, with sha-256 or sha-512, for example sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. It is required when the request has a body and the credential has a public key, and in that case Signature-Input must include the content-digest component.
Body
What the card is tied to. Defines the required identifier (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, a decimal with up to 2 places (e.g. 1250.00), in BRL. Required for HOTEL and AERIAL, forbidden for CUSTOM. The sum rate + taxes + fees must be greater than zero and sets the ceiling.
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, as a Brasília day. Omitted, it is the issuance day. It cannot be earlier than today. See Usage window.
2027-03-10End of the usage window, YYYY-MM-DD, inclusive, as a Brasília day. Omitted, it is the type default: checkOut + 20 days for HOTEL, issuance + 1 day for AERIAL, issuance + 60 days for CUSTOM. At most 365 days from the issuance day. See Date limits.
2027-05-07Maximum number of authorizations on the card, up to 100000. Overrides the type default (AERIAL 2 · HOTEL 3 · CUSTOM 10000).
3Ceiling period: TOTAL (default, the whole window), MONTHLY (renews every month) or DAILY (renews every day). Accepted for all three types. See Ceiling period.
TOTALMONTHLYDAILYLodging data. Required when type is HOTEL and forbidden for other types.
Air booking data. Required when type is AERIAL and forbidden for other types.
Identifier of what the CUSTOM card pays for, defined by you (e.g. the supplier id), as a 1-to-255-character string; it is the idempotency key, so do not use personal data. Only CUSTOM sends this field: for HOTEL and AERIAL, the key comes from hotelBooking.reservationId or flightBooking.recordLocator and returns in reference in the response, and sending reference gives 400 bad-request-exception with field body.reference. See Idempotency and reissuance.
SUP-000123Governance fields (e.g. cost center), 1 to 50 items. They show up in the transaction data on the card network, for reconciliation: never use personal data (CPF, passenger name, email, phone).
Who requests the issuance, update or cancellation, for auditing. Send a user's e-mail or, for an automated call, an identifier from your system. Free text, 1 to 100 characters.
agente@exemplo.test