Criar VCN (Em breve)
🚧 Em breve — este endpoint ainda não está disponível em Sandbox nem Produção. A documentação está publicada para você preparar a integração; avisaremos no changelog quando entrar no ar.
Emite um cartão virtual (VCN) vinculado a uma reserva de hospedagem (HOTEL), a uma reserva aérea (AERIAL) ou a um uso definido por você (CUSTOM — ex.: um cartão por fornecedor). Retorna PAN, CVV e validade de forma síncrona.
Envie exatamente um bloco, o do seu type — hotelBooking, flightBooking ou reference —, levando dentro dele a chave de idempotência (reservationId, recordLocator — o PNR, Passenger Name Record — ou reference.id). Nos tipos de reserva você informa o custo (amount) e o teto do cartão é derivado dele; no CUSTOM você informa o teto (limit) e não envia amount. As regras de cada campo estão documentadas no próprio campo, abaixo; o comportamento de cada erro, em Respostas.
Guarde o vcnId da resposta: é ele que endereça a recarga em Atualizar VCN e a reobtenção dos dados do cartão em Revelar dados do VCN.
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": "Token de acesso inválido ou expirado.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 401
}
{
"error": "Forbidden",
"message": "Você não tem permissão para realizar esta operação.",
"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.
Token Bearer obtido via OAuth 2.0 Client Credentials. Formato: Bearer TOKEN
Bearer TOKENThe media type of the request body
Vínculo do cartão. Define o bloco obrigatório (HOTEL → hotelBooking, AERIAL → flightBooking, CUSTOM → reference) e como o teto nasce: derivado do amount nos tipos de reserva, informado em limit no CUSTOM.
Custo da reserva, em decimal com no máximo 2 casas (ex.: 1250.00). Obrigatório em `HOTEL` e `AERIAL`; proibido em `CUSTOM`, que declara o teto direto em limit. A soma rate + taxes + fees precisa ser maior que zero e define o teto derivado do cartão. Um valor com mais de 2 casas decimais é recusado com 400 — não é arredondado.
Teto de gasto do cartão. Obrigatório em `CUSTOM`; proibido em HOTEL/AERIAL, em que o teto é derivado do amount.
Início da janela de uso, YYYY-MM-DD, aceito nos três tipos. Omitido, a janela abre no instante da emissão. Informado, não pode ser um dia anterior ao da emissão, e o endDate tem de ser posterior a ele — senão, 400 invalid-vcn-request.
Fim da janela de uso, YYYY-MM-DD, aceito nos três tipos. Se informado, prevalece sobre a validade derivada (HOTEL = checkOut + 20 dias · AERIAL = emissão + 1 dia · CUSTOM = emissão + 60 dias). Teto: 365 dias da emissão — contados da emissão mesmo quando você informa startDate, então adiar o início não estende o teto. Além disso, 400 invalid-vcn-request.
Número máximo de autorizações no cartão, até 100000. Sobrescreve o default do tipo (AERIAL 2 · HOTEL 3 · CUSTOM 10000).
Dados da hospedagem. Obrigatório quando `type` for `HOTEL` e proibido nos outros tipos.
Dados da reserva aérea. Obrigatório quando `type` for `AERIAL` e proibido nos outros tipos.
Vínculo do cartão CUSTOM, definido por você (um fornecedor, um contrato, uma conta a pagar). Obrigatório quando `type` for `CUSTOM` e proibido nos outros tipos.
Campos de governança do cliente. Se enviado, precisa ter no mínimo 1 item.
Quem solicitou a emissão, para auditoria. email e phone são de uso interno e não são compartilhados.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Token Bearer obtido via OAuth 2.0 Client Credentials. Formato: Bearer TOKEN
Body
Vínculo do cartão. Define o bloco obrigatório (HOTEL → hotelBooking, AERIAL → flightBooking, CUSTOM → reference) e como o teto nasce: derivado do amount nos tipos de reserva, informado em limit no CUSTOM.
HOTELAERIALCUSTOMCusto da reserva, em decimal com no máximo 2 casas (ex.: 1250.00). Obrigatório em HOTEL e AERIAL; proibido em CUSTOM, que declara o teto direto em limit. A soma rate + taxes + fees precisa ser maior que zero e define o teto derivado do cartão. Um valor com mais de 2 casas decimais é recusado com 400 — não é arredondado.
Teto de gasto do cartão. Obrigatório em CUSTOM; proibido em HOTEL/AERIAL, em que o teto é derivado do amount.
Início da janela de uso, YYYY-MM-DD, aceito nos três tipos. Omitido, a janela abre no instante da emissão. Informado, não pode ser um dia anterior ao da emissão, e o endDate tem de ser posterior a ele — senão, 400 invalid-vcn-request.
2026-09-10Fim da janela de uso, YYYY-MM-DD, aceito nos três tipos. Se informado, prevalece sobre a validade derivada (HOTEL = checkOut + 20 dias · AERIAL = emissão + 1 dia · CUSTOM = emissão + 60 dias). Teto: 365 dias da emissão — contados da emissão mesmo quando você informa startDate, então adiar o início não estende o teto. Além disso, 400 invalid-vcn-request.
2026-10-27Número máximo de autorizações no cartão, até 100000. Sobrescreve o default do tipo (AERIAL 2 · HOTEL 3 · CUSTOM 10000).
3Dados da hospedagem. Obrigatório quando type for HOTEL e proibido nos outros tipos.
Dados da reserva aérea. Obrigatório quando type for AERIAL e proibido nos outros tipos.
Vínculo do cartão CUSTOM, definido por você (um fornecedor, um contrato, uma conta a pagar). Obrigatório quando type for CUSTOM e proibido nos outros tipos.
Campos de governança do cliente. Se enviado, precisa ter no mínimo 1 item.
Quem solicitou a emissão, para auditoria. email e phone são de uso interno e não são compartilhados.