Recurrences

Recurrences

A recurrence is the payer's mandate: their authorization for you to charge them. It defines who pays, how much, how often and for how long. On this page you will find the endpoints to create, get, list, update and cancel recurrences.

Available Endpoints

  • Production: https://api.pixtopay.com.br/v2/automatic-pix/recurrences

Create recurrence

Creates the recurrence the payer will authorize. The response already carries the authorization QR code.

Route

POST /v2/automatic-pix/recurrences

Headers

{
  "Authorization": "YOUR_API_KEY",
  "Content-Type": "application/json"
}

Body

ParameterTypeRequiredDescription
transaction_idstringYesYour identifier for the recurrence. At most 35 characters, unique in your account. It is the identifier the payer's banking app shows, so prefer something meaningful to them. Above 35 characters the request is refused, not truncated.
objectstringNoDescription of the subscription, at most 35 characters (e.g. "Plano Gold mensal"). In journey 3, it is the text shown to the payer on the immediate payment.
debtorobjectYesThe payer. It is the same for the whole life of the recurrence.
debtor.document_numberstringYesCPF (11 digits) or CNPJ (14 digits), digits only. The check digit is validated.
debtor.namestringYesPayer name, at most 100 characters.
debtor.emailstringNoValid email, at most 140 characters.
debtor.addressobjectNoPayer address. Optional as a whole, complete if sent: with the object, the four fields below are required.
debtor.address.streetstringYes*Street with number, at most 200 characters.
debtor.address.citystringYes*City, at most 200 characters.
debtor.address.statestringYes*State with exactly 2 upper-case letters (e.g. "SP").
debtor.address.zip_codestringYes*CEP with exactly 8 digits, no hyphen.
scheduleobjectYesThe recurrence's calendar.
schedule.start_datestringYesYYYY-MM-DD. Date from which the recurrence is valid. It must be after today, in Brasília time.
schedule.end_datestringNoYYYY-MM-DD, after start_date. Omit it for an open-ended subscription. It cannot be changed afterwards.
schedule.periodicitystringYesWEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL or ANNUAL.
amountnumberYesFixed amount of each charge, in reais, with up to 2 decimal places (e.g. 99.90). It is the amount charged every cycle.
retry_policystringYesNOT_ALLOWED or ALLOWS_3R_7D. It cannot be changed afterwards.
business_day_adjustbooleanNotrue to move a due date that falls on a weekend or holiday to the next business day. Default false: the debit happens on the exact date. It can be changed later with PATCH.
charge_lead_daysintegerNoHow many days before each due date PixToPay creates the cycle's charge: 3 to 10. Default 5. Banco Central allows 2, but the minimum here is 3 so a failed day can still be recovered before the D-2 deadline. It can be changed later with PATCH.
webhookstringNoURL (max. 255 characters) that receives the events of this recurrence and its charges, and the callback of each payment. See Notifications. Recommended.
activation_amountnumberNoAmount of the immediate payment of journey 3. When present, the API creates the payment and binds it to the recurrence.
activation_expires_inintegerNoFor how many seconds the activation payment stays payable. Default 3600 (1 hour), maximum 86400 (24 hours). Only takes effect with activation_amount.
location_idintegerNoOnly to reuse an existing QR location. When omitted, the API creates one. If in doubt, omit it.

* Required when debtor.address is sent.

⚠️

Send only the fields in the table above. Any other field in the body, even a single misspelled name, gets the whole request refused with 400, and nothing is created. The message names the fields that are not accepted:

{ "type": "ValidationError", "message": "`plano`, `valor` is not a field of this endpoint" }

Date rules. schedule.start_date must be after today, in Brasília time: today's date is refused. schedule.end_date, when sent, must be after schedule.start_date. Outside these rules the response is 400 naming the field, and nothing is created.

Request example:

curl --location 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences' \
--header 'Authorization: API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "transaction_id": "assinatura-8891",
    "object": "Plano Gold mensal",
    "debtor": {
        "document_number": "12345678909",
        "name": "Maria Silva",
        "email": "maria.silva@exemplo.com.br",
        "address": {
            "street": "Rua das Acacias, 128",
            "city": "Belo Horizonte",
            "state": "MG",
            "zip_code": "30140071"
        }
    },
    "schedule": {
        "start_date": "2026-10-01",
        "end_date": "2027-10-01",
        "periodicity": "MONTHLY"
    },
    "amount": 99.90,
    "retry_policy": "ALLOWS_3R_7D",
    "business_day_adjust": true,
    "charge_lead_days": 5,
    "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}'

Response model [2xx]

ParameterTypeDescription
recurrence_idstringRecurrence identifier. Store it: you use it in every following endpoint.
statusstringRecurrence status. A new recurrence is born CREATED.
contractstringEcho of the transaction_id you sent. It is the identifier the payer sees in their banking app.
debtorobjectPayer document (document_number) and name (name). Email and address are stored and travel with the charges, but are not echoed.
scheduleobjectstart_date, end_date (null if open-ended) and periodicity.
amountnumberAmount of each charge.
retry_policystringRetry policy.
business_day_adjustbooleanWhether a due date on a weekend or holiday moves to the next business day.
charge_lead_daysintegerHow many days in advance each cycle's charge is created.
journeystringAWAITING_DEFINITION until the payer authorizes.
pix_copy_pastestringThe recurrence's Pix copy-and-paste code, as text. It is what the payer pastes in their banking app to authorize.
qrcodestringThe same code as a base64 PNG image (data URI), ready for <img src="...">. It is the QR code the payer scans. If it is missing, get the recurrence with GET /recurrences/:recurrence_id.
webhookstringThe recurrence's notification URL, or null.
activationobjectOnly in journey 3 with activation_amount: charge_id and amount of the immediate payment.

Response model [4xx]

ParameterTypeDescription
typestringValidationError or ProviderError
messagestringMessage describing the error, naming the field

Response 201:

{
  "recurrence_id": "RR9012345620260922f3a1c7b28e4",
  "status": "CREATED",
  "contract": "assinatura-8891",
  "debtor": {
    "document_number": "12345678909",
    "name": "Maria Silva"
  },
  "schedule": {
    "start_date": "2026-10-01",
    "end_date": "2027-10-01",
    "periodicity": "MONTHLY"
  },
  "amount": 99.9,
  "retry_policy": "ALLOWS_3R_7D",
  "business_day_adjust": false,
  "charge_lead_days": 5,
  "journey": "AWAITING_DEFINITION",
  "pix_copy_paste": "00020126850014br.gov.bcb.pix2563qrcode.exemplo/v2/9f2a...6304A1B2",
  "qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}

Journey 3: authorize and charge in the same scan

Send activation_amount so that the same QR code charges an immediate payment right away and authorizes the recurrence.

Request example:

curl --location 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences' \
--header 'Authorization: API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "transaction_id": "assinatura-8892",
    "object": "Plano Gold mensal",
    "debtor": {
        "document_number": "12345678909",
        "name": "Maria Silva"
    },
    "schedule": {
        "start_date": "2026-11-01",
        "periodicity": "MONTHLY"
    },
    "amount": 99.90,
    "retry_policy": "ALLOWS_3R_7D",
    "activation_amount": 99.90,
    "activation_expires_in": 3600,
    "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}'

Response 201:

{
  "recurrence_id": "RR9012345620260922b7d2e9a14c1",
  "status": "CREATED",
  "contract": "assinatura-8892",
  "debtor": {
    "document_number": "12345678909",
    "name": "Maria Silva"
  },
  "schedule": {
    "start_date": "2026-11-01",
    "end_date": null,
    "periodicity": "MONTHLY"
  },
  "amount": 99.9,
  "retry_policy": "ALLOWS_3R_7D",
  "business_day_adjust": false,
  "charge_lead_days": 5,
  "journey": "AWAITING_DEFINITION",
  "pix_copy_paste": "00020126850014br.gov.bcb.pix2563qrcode.exemplo/v2/7c41...63041E9F",
  "qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "activation": {
    "charge_id": "c2a8e41f70b94d3ca5e61b8027fd394a",
    "amount": 99.9
  },
  "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}

The activation payment is separate from the cycles: automatic charges start at schedule.start_date, as on any recurrence. To charge the activation today and the next debit a month from now, send start_date one month ahead. It appears in GET /charges as a charge of the recurrence, with "type": "activation", and reaches you as a paid Pix deposit, with transaction_id equal to <recurrence transaction_id>-ativacao.

Response 400 duplicate transaction_id:

{
  "type": "ValidationError",
  "message": "body.transaction_id already exists"
}

Response 400 unknown field:

{
  "type": "ValidationError",
  "message": "`plano`, `valor` is not a field of this endpoint"
}

See every message of this endpoint in Errors.


Get recurrence

Gets a recurrence with its current state, fetched at the time of the call. This is the call to find out whether the payer has authorized.

Route

GET /v2/automatic-pix/recurrences/:recurrence_id

Headers

{
  "Authorization": "YOUR_API_KEY"
}

Parameters

ParameterWhereRequiredDescription
recurrence_idpathYesThe recurrence_id returned on creation.

For a journey 3 recurrence (created with activation_amount), the read returns the combined QR, which charges and authorizes in the same scan. Once the activation payment has expired unpaid, the read answers with pix_copy_paste: null and no qrcode: the recurrence can no longer be authorized with its activation. Cancel it and create a new one.

A recurrence that has ended (CANCELLED, REJECTED or EXPIRED) is read with pix_copy_paste: null and no qrcode: it has no QR to show.

Request example:

curl --location 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences/RR9012345620260922f3a1c7b28e4' \
--header 'Authorization: API_KEY'

Response 200:

{
  "recurrence_id": "RR9012345620260922f3a1c7b28e4",
  "status": "APPROVED",
  "contract": "assinatura-8891",
  "debtor": {
    "document_number": "12345678909",
    "name": "Maria Silva"
  },
  "schedule": {
    "start_date": "2026-10-01",
    "end_date": "2027-10-01",
    "periodicity": "MONTHLY"
  },
  "amount": 99.9,
  "retry_policy": "ALLOWS_3R_7D",
  "business_day_adjust": false,
  "charge_lead_days": 5,
  "journey": "JOURNEY_2",
  "pix_copy_paste": "00020126850014br.gov.bcb.pix2563qrcode.exemplo/v2/9f2a...6304A1B2",
  "qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}

Same format as the creation response, with status and journey updated.

Response 404:

{
  "message": "Recurrence not found"
}

The 404 covers both an identifier that does not exist and one that does not belong to your account. Both answer the same way, on purpose.


List recurrences

Lists the recurrences you created in a period, newest first.

Route

GET /v2/automatic-pix/recurrences

Headers

{
  "Authorization": "YOUR_API_KEY"
}

Query Parameters

ParameterTypeRequiredDescription
startstring (ISO 8601)YesStart of the period, with time zone (e.g. 2026-09-01T00:00:00-03:00). Compared with the creation date.
endstring (ISO 8601)YesEnd of the period, with time zone.
pageintegerNoPage, starting at 0. Default 0.
page_sizeintegerNoItems per page. Default and maximum 100: larger values become 100.

Request example:

curl --location 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences?start=2026-09-01T00:00:00Z&end=2026-10-01T00:00:00Z&page=0&page_size=100' \
--header 'Authorization: API_KEY'

Response 200:

{
  "pagination": {
    "current_page": 0,
    "page_size": 100,
    "total_pages": 3,
    "total_items": 260
  },
  "recurrences": [
    {
      "recurrence_id": "RR9012345620260922f3a1c7b28e4",
      "status": "APPROVED",
      "contract": "assinatura-8891",
      "debtor": { "document_number": "12345678909", "name": "Maria Silva" },
      "schedule": {
        "start_date": "2026-10-01",
        "end_date": "2027-10-01",
        "periodicity": "MONTHLY"
      },
      "amount": 99.9,
      "retry_policy": "ALLOWS_3R_7D",
      "business_day_adjust": false,
      "charge_lead_days": 5,
      "journey": "JOURNEY_2",
      "pix_copy_paste": "00020126850014br.gov.bcb.pix2563qrcode.exemplo/v2/9f2a...6304A1B2",
      "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
    }
  ]
}
  • The list does not include qrcode, only pix_copy_paste. For the image, get the recurrence individually.

Response 400 missing period:

{
  "type": "ValidationError",
  "message": "start and end are required"
}

Update or cancel recurrence

Route

PATCH /v2/automatic-pix/recurrences/:recurrence_id

Headers

{
  "Authorization": "YOUR_API_KEY",
  "Content-Type": "application/json"
}

Body

Send at least one of these fields:

ParameterTypeDescription
debtor_namestringCorrects the payer's name. At most 140 characters; prefer up to 100, the limit of the name on charges.
start_datestringYYYY-MM-DD. Moves the start date later or earlier. Same rule as creation: after today, in Brasília time.
statusstringCANCELLED. Ends the recurrence.
webhookstringReplaces the recurrence's notification URL. "" or null clears it.
business_day_adjustbooleanTurns the move to the next business day on or off. Applies to charges not yet created.
charge_lead_daysintegerNew lead time, 3 to 10 days. Applies to charges not yet created.
⚠️

Amount, periodicity, end date and retry policy do not change. Sending amount, periodicity, end_date, retry_policy, object, debtor, schedule, location_id or contract is refused with 400, naming the field. A price or plan change is a new recurrence: cancel the current one, create another with a new transaction_id and ask the payer to authorize again.

Cancelling is the only way to end a recurrence, and CANCELLED is the only status you can set. There is no deletion. Cancelling the recurrence does not cancel charges already issued: if a cycle's charge is waiting for its due date and you do not want to collect it, cancel it too, with PATCH /charges/:charge_id.

Replacing the webhook:

  • A PATCH with only webhook just stores the new URL and answers.
  • The change also applies to the recurrence's pending charges: their payment is notified at the new URL. Charges already paid are not touched.
  • The journey 3 activation payment keeps the URL in effect when the recurrence was created.

Request example (cancel):

curl --location --request PATCH 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences/RR9012345620260922f3a1c7b28e4' \
--header 'Authorization: API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "status": "CANCELLED"
}'

Request example (correct the name):

curl --location --request PATCH 'https://api.pixtopay.com.br/v2/automatic-pix/recurrences/RR9012345620260922f3a1c7b28e4' \
--header 'Authorization: API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "debtor_name": "Maria S. Silva"
}'

Response 200:

{
  "recurrence_id": "RR9012345620260922f3a1c7b28e4",
  "status": "APPROVED",
  "contract": "assinatura-8891",
  "debtor": {
    "document_number": "12345678909",
    "name": "Maria S. Silva"
  },
  "schedule": {
    "start_date": "2026-10-01",
    "end_date": "2027-10-01",
    "periodicity": "MONTHLY"
  },
  "amount": 99.9,
  "retry_policy": "ALLOWS_3R_7D",
  "business_day_adjust": false,
  "charge_lead_days": 5,
  "journey": "JOURNEY_2",
  "pix_copy_paste": "00020126850014br.gov.bcb.pix2563qrcode.exemplo/v2/9f2a...6304A1B2",
  "qrcode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "webhook": "https://loja.exemplo.com.br/callbacks/pixtopay"
}

A PATCH whose result is CANCELLED, REJECTED or EXPIRED answers with pix_copy_paste: null and no qrcode: a recurrence that has ended has no QR to show.

Response 400 field that cannot be changed:

{
  "type": "ValidationError",
  "message": "`amount`, `periodicity` cannot be changed after a recurrence is created. A recurrence whose value, cadence or end date must change has to be cancelled and recreated under a new contract, and re-authorised by the payer"
}

Response 400 empty body:

{
  "type": "ValidationError",
  "message": "body must set at least one changeable field: `debtor_name`, `start_date`, `status`, `webhook`, `business_day_adjust`, `charge_lead_days`"
}