curl --request POST \
--url https://api.sandbox.z2pay.com/v1/plans \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"code": "<string>",
"name": "<string>",
"recurrence": {
"interval": 1,
"anchorDay": 16,
"collectionTiming": "prepaid"
},
"items": [
{
"item": {
"key": "<string>",
"name": "<string>",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": "<string>",
"metadata": {}
},
"price": {
"amount": 1,
"billingScheme": "fixed",
"currency": "BRL"
}
}
],
"description": "<string>",
"metadata": {}
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
code: '<string>',
name: '<string>',
recurrence: {interval: 1, anchorDay: 16, collectionTiming: 'prepaid'},
items: [
{
item: {
key: '<string>',
name: '<string>',
kind: 'recurring',
quantityDefault: 1,
displayOrder: 0,
description: '<string>',
metadata: {}
},
price: {amount: 1, billingScheme: 'fixed', currency: 'BRL'}
}
],
description: '<string>',
metadata: {}
})
};
fetch('https://api.sandbox.z2pay.com/v1/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sandbox.z2pay.com/v1/plans"
payload = {
"code": "<string>",
"name": "<string>",
"recurrence": {
"interval": 1,
"anchorDay": 16,
"collectionTiming": "prepaid"
},
"items": [
{
"item": {
"key": "<string>",
"name": "<string>",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": "<string>",
"metadata": {}
},
"price": {
"amount": 1,
"billingScheme": "fixed",
"currency": "BRL"
}
}
],
"description": "<string>",
"metadata": {}
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "plan_lhutpqeq2ml3stia4vn90xars",
"code": "pro-monthly",
"name": "Pro Plan",
"description": "Pro tier with all features",
"status": "active",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"trialSpec": null,
"metadata": {},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"items": [
{
"id": "pli_oaimno59ai3uuqwq0ti7gxs0j",
"planId": "plan_lhutpqeq2ml3stia4vn90xars",
"key": "default",
"name": "Pro Subscription",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": null,
"metadata": {},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"currentPrice": {
"id": "price_l1r8693wk6ksbd9044bwvwu93",
"planItemId": "pli_oaimno59ai3uuqwq0ti7gxs0j",
"planId": "plan_lhutpqeq2ml3stia4vn90xars",
"billingScheme": "fixed",
"amount": 9900,
"currency": "BRL",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"trialSpec": null,
"isCurrent": true,
"publishedAt": "2025-06-29T13:45:30.000Z",
"archivedAt": null,
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z"
}
}
]
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"issues": [
{
"path": "status",
"message": "Status inválido. Valores aceitos: pending, waiting_payment, paid, refused, canceled, refunded"
},
{
"path": "startDate",
"message": "Data deve ser ISO 8601 com timezone (ex.: 2026-06-24T00:00:00Z)"
}
]
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}{
"error": {
"code": "CONFLICT",
"message": "No refundable payment found"
}
}{
"error": "Idempotency key already used with a different request body"
}Criar plano
Cria o plano com todos os seus itens e preços, já publicado e pronto para receber assinaturas.
curl --request POST \
--url https://api.sandbox.z2pay.com/v1/plans \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"code": "<string>",
"name": "<string>",
"recurrence": {
"interval": 1,
"anchorDay": 16,
"collectionTiming": "prepaid"
},
"items": [
{
"item": {
"key": "<string>",
"name": "<string>",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": "<string>",
"metadata": {}
},
"price": {
"amount": 1,
"billingScheme": "fixed",
"currency": "BRL"
}
}
],
"description": "<string>",
"metadata": {}
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
code: '<string>',
name: '<string>',
recurrence: {interval: 1, anchorDay: 16, collectionTiming: 'prepaid'},
items: [
{
item: {
key: '<string>',
name: '<string>',
kind: 'recurring',
quantityDefault: 1,
displayOrder: 0,
description: '<string>',
metadata: {}
},
price: {amount: 1, billingScheme: 'fixed', currency: 'BRL'}
}
],
description: '<string>',
metadata: {}
})
};
fetch('https://api.sandbox.z2pay.com/v1/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.sandbox.z2pay.com/v1/plans"
payload = {
"code": "<string>",
"name": "<string>",
"recurrence": {
"interval": 1,
"anchorDay": 16,
"collectionTiming": "prepaid"
},
"items": [
{
"item": {
"key": "<string>",
"name": "<string>",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": "<string>",
"metadata": {}
},
"price": {
"amount": 1,
"billingScheme": "fixed",
"currency": "BRL"
}
}
],
"description": "<string>",
"metadata": {}
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "plan_lhutpqeq2ml3stia4vn90xars",
"code": "pro-monthly",
"name": "Pro Plan",
"description": "Pro tier with all features",
"status": "active",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"trialSpec": null,
"metadata": {},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"items": [
{
"id": "pli_oaimno59ai3uuqwq0ti7gxs0j",
"planId": "plan_lhutpqeq2ml3stia4vn90xars",
"key": "default",
"name": "Pro Subscription",
"kind": "recurring",
"quantityDefault": 1,
"displayOrder": 0,
"description": null,
"metadata": {},
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z",
"currentPrice": {
"id": "price_l1r8693wk6ksbd9044bwvwu93",
"planItemId": "pli_oaimno59ai3uuqwq0ti7gxs0j",
"planId": "plan_lhutpqeq2ml3stia4vn90xars",
"billingScheme": "fixed",
"amount": 9900,
"currency": "BRL",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"trialSpec": null,
"isCurrent": true,
"publishedAt": "2025-06-29T13:45:30.000Z",
"archivedAt": null,
"createdAt": "2025-06-29T13:45:30.000Z",
"updatedAt": "2025-06-29T13:45:30.000Z"
}
}
]
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"issues": [
{
"path": "status",
"message": "Status inválido. Valores aceitos: pending, waiting_payment, paid, refused, canceled, refunded"
},
{
"path": "startDate",
"message": "Data deve ser ISO 8601 com timezone (ex.: 2026-06-24T00:00:00Z)"
}
]
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}{
"error": {
"code": "CONFLICT",
"message": "No refundable payment found"
}
}{
"error": "Idempotency key already used with a different request body"
}POST /plans
Faz parte do recurso Planos e Preços — o item, o preço versionado e os
status estão lá.
Cria a oferta inteira numa chamada: o plano, cada entrada de items com o seu preço, e a
publicação. A resposta tem a mesma forma de GET /plans/{id} — o
plano com os itens e o preço em vigor de cada um.
active, aceitando assinaturas. O status draft
existe para o painel, onde uma tela precisa salvar um plano pela metade — uma chamada HTTP monta o
objeto inteiro antes de enviar, e exigir uma publicação depois deixaria um plano que existe sem
funcionar.kind: "recurring". Um plano só de activation não sustenta
assinatura: a adesão cobra uma vez e não recorre, então não haveria o que faturar no segundo
ciclo. A requisição responde 400 apontando items.key não se repete dentro do plano. É por ela que a assinatura identifica o item, e duas
iguais tornariam a referência ambígua. A resposta 400 aponta o índice do segundo item que a
usou.trialSpec num plano cujos itens são todos
activation responde 400: diferir a única cobrança que a adesão tem não significa nada.recurrence e trialSpec vão
na raiz, e o preço de cada item os herda — a assinatura tem um ciclo só, e dois itens com
cadências diferentes não teriam quando cobrar juntos. A exceção é o item activation, que nunca
recebe o teste mesmo com trialSpec preenchido na raiz.code é seu identificador do plano, e é único na conta. Repetir um code já usado responde
409 — inclusive se o plano anterior estiver arquivado, porque arquivar não libera o código.Exemplo
curl -X POST https://api.sandbox.z2pay.com/v1/plans \
-H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
-H "Content-Type: application/json" \
-d '{
"code": "pro-monthly",
"name": "Plano Pro",
"description": "Todos os recursos, cobrado mensalmente",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"items": [
{
"item": { "key": "default", "name": "Assinatura Pro", "kind": "recurring" },
"price": { "amount": 9900, "currency": "BRL" }
}
]
}'
{
"id": "plan_lhutpqeq2ml3stia4vn90xars",
"code": "pro-monthly",
"name": "Plano Pro",
"status": "active",
"recurrence": {
"interval": 1,
"unit": "month",
"anchor": "subscription_start",
"collectionTiming": "prepaid"
},
"trialSpec": null,
"items": [
{
"id": "pli_oaimno59ai3uuqwq0ti7gxs0j",
"key": "default",
"name": "Assinatura Pro",
"kind": "recurring",
"quantityDefault": 1,
"currentPrice": {
"id": "price_l1r8693wk6ksbd9044bwvwu93",
"amount": 9900,
"currency": "BRL",
"isCurrent": true
}
}
],
"createdAt": "2026-08-10T13:45:30.000Z"
}
Authorizations
API Key da Credential (gerada no Backoffice)
Headers
Chave única para garantir idempotência da requisição
Body
Identificador único do plano na sua conta. Apenas letras minúsculas, números, hífen e underscore.
1 - 100^[a-z0-9-_]+$Nome do plano.
1 - 255Cadência da cobrança: a cada quantas unidades (interval), qual unidade (unit), a âncora do ciclo e se cobra no início ou no fim. Vale para todos os itens recorrentes.
Show child attributes
Show child attributes
Itens do plano, cada um com seu preço. Ao menos um deve ser kind: "recurring".
1Show child attributes
Show child attributes
Descrição livre. Opcional.
1000Objeto livre de chave/valor para dados seus. Devolvido nas respostas e nos webhooks.
Show child attributes
Show child attributes
Período de teste padrão da oferta. A assinatura pode sobrescrevê-lo.
Show child attributes
Show child attributes
Response
Plano criado, com os itens e o preço de cada um
Identificador único do registro.
Código de identificação do recurso (ex.: código do plano ou do contrato).
Nome de exibição do plano ou do componente.
Descrição do item (item do plano ou linha da fatura).
Status atual do registro (assinatura, fatura, plano ou slip de pagamento).
Cadência da cobrança: a cada quantas unidades (interval), qual unidade (unit), a âncora do ciclo e se cobra no início ou no fim. Vale para todos os itens recorrentes.
Período de teste padrão da oferta. A assinatura pode sobrescrevê-lo.
Metadados livres (pares chave-valor) para uso do integrador; não afeta o processamento.
Data e hora de criação do registro (ISO 8601).
Data e hora da última atualização do registro (ISO 8601).
Itens do plano, cada um com o preço em vigor.
Show child attributes
Show child attributes