Pendencies API — Functional Documentation
Table of contents
- Overview
- Actors and context
- Supported pendencies
- End-to-end onboarding flow
- Operations
- data_grid attribute catalog
- Business rules and constraints
- Data protection (masking)
- Error meanings
Overview
Using this API, a partner can:
- Query a merchant's open pendencies and their current status.
- Submit or update registration data.
- Request and validate contact-channel verification codes (SMS / email / WhatsApp).
- Upload required documents (as Base64 content).
- Accept documents and terms.
- Download generated documents when available.
snake_case, dates are ISO-8601 UTC, and the content type is
application/json.Actors and context
| Field | Description |
|---|---|
partnerId | Unique identifier of the partner application. |
merchantId | Identifier of the merchant whose onboarding is being managed. |
Both identifiers appear in the path of every endpoint:
person_type:natural_person— the merchant's legal document is a CPF (individual).company— the merchant's legal document is a CNPJ (legal entity).
The person type determines which registration attributes apply (see data_grid attribute catalog).
Supported pendencies
Only the pendencies below are exposed to partners. Any other pendency the platform tracks internally is never returned.
| Pendency | Meaning | Resolved via |
|---|---|---|
cell_phone_validation | Cell phone ownership must be verified | token request + validation |
email_validation | Email ownership must be verified | token request + validation |
data_grid | Registration attributes must be provided/updated | PUT /data-grid |
selfie_upload | Selfie must be uploaded | POST /upload-document |
identification_document_upload | Identification document must be uploaded | POST /upload-document |
social_contract_upload | Social contract must be uploaded | POST /upload-document |
letter_of_attorney_upload | Power of attorney must be uploaded | POST /upload-document |
order_summary | Order summary must be accepted | PUT /acceptance-document |
terms_and_conditions | Terms and conditions must be accepted | PUT /acceptance-document |
privacy_policy | Privacy policy must be accepted | PUT /acceptance-document |
pendencies: []).data_grid pendency is returned and it is pending, its grid_info field lists exactly
which registration attributes must be submitted.cell_phone_validation / email_validation pendency is returned, its data field carries
the masked contact value the verification code will be sent to, so the partner can show the
merchant which channel is going to be used.End-to-end onboarding flow
A partner first queries the merchant's pendencies, then resolves each one respecting the ordering rules below. Only pendencies that are actually open for that merchant need to be resolved.
- Contact validation comes first. The partner never sends the contact value to the token
endpoints: the API reads it from the merchant's
email_validation/cell_phone_validationpendency. Therefore the matchingemail/cell_phonevalue must already exist in the registration (submitted viadata_grid); otherwise the token request is rejected with422. - Identification document after the selfie, when the selfie is required.
- Social contract before power of attorney. The merchant provides the social contract or the power of attorney depending on their situation.
Operations
/api/v1/partner/{partnerId}/merchant/{merchantId}/pendencies/swagger-ui.html; the OpenAPI spec at /api-docs.| Method | Route | Success |
|---|---|---|
GET | (base path) | 200 |
POST | /token-request?type= | 202 |
POST | /token-validation?type= | 200 |
PUT | /data-grid | 204 |
POST | /upload-document | 200 |
PUT | /acceptance-document | 200 |
GET | /download-document/{documentType} | 200 |
1. Query pendencies
GET (base path)person_type and overall situations.{
"person_type": "natural_person",
"situations": [
{ "status": "active", "status_update_date": "2026-07-02T20:08:04.155Z" }
],
"pendencies": [
{
"pendency_type": "email_validation",
"situation": { "status": "pending", "status_update_date": "2026-07-02T20:08:04.155Z" },
"data": { "type": "email", "value": "t***@email.com" }
},
{
"pendency_type": "data_grid",
"situation": { "status": "pending", "status_update_date": "2026-07-02T20:08:04.155Z" },
"grid_info": [
{ "attribute": "email", "required": true },
{ "attribute": "residential_address", "required": true }
]
}
]
}{
"person_type": "natural_person",
"situations": [
{ "status": "active", "status_update_date": "2026-07-02T20:08:04.155Z" }
],
"pendencies": [
{
"pendency_type": "email_validation",
"situation": { "status": "pending", "status_update_date": "2026-07-02T20:08:04.155Z" },
"data": { "type": "email", "value": "t***@email.com" }
},
{
"pendency_type": "data_grid",
"situation": { "status": "pending", "status_update_date": "2026-07-02T20:08:04.155Z" },
"grid_info": [
{ "attribute": "email", "required": true },
{ "attribute": "residential_address", "required": true }
]
}
]
}Response fields:
| Field | Description |
|---|---|
person_type | natural_person or company, derived from the merchant's legal document. |
situations[] | Overall situation of the merchant (status + status_update_date). |
pendencies[].pendency_type | The pendency identifier (see supported pendencies). |
pendencies[].situation | status + status_update_date (ISO-8601 UTC). |
pendencies[].grid_info[] | Only for data_grid when the pendency is pending: the attributes to submit, each with attribute and required. |
pendencies[].data | Only for email_validation / cell_phone_validation: { "type": "email" | "cell_phone", "value": "<masked>" }. |
Notes:
- The merchant's legal document number is not returned.
- Omitted (null) fields are not serialized.
- Merchant not found / not accessible →
404. - No applicable pendencies →
200with an empty list.
situation.status values: active, inactive, created, success, failure, retry,
approved, pending, received, reopened, dismissed, dismiss_analysis, reproved,
finished, analysis, canceled.2002. Request validation code
POST /token-request?type={channel}| Parameter | In | Required | Description |
|---|---|---|---|
type | query | yes | Contact channel: cell_phone, email or whatsapp (case-insensitive). |
email_validation for email, cell_phone_validation for cell_phone / whatsapp).
If no contact value is available there, the request fails with 422.{
"sms_token_validation_id": "b1e3...",
"cell_phone": "(51) 9****-7923",
"acquirer_merchant_code": "123456",
"situation": { "status": "pending" }
}{
"sms_token_validation_id": "b1e3...",
"cell_phone": "(51) 9****-7923",
"acquirer_merchant_code": "123456",
"situation": { "status": "pending" }
}situation.status for the token session is pending or ok.202 (accepted / dispatched)3. Validate code
POST /token-validation?type={channel}Submits the code the merchant received to confirm ownership of the contact channel.
| Parameter | In | Required | Description |
|---|---|---|---|
type | query | yes | Contact channel: cell_phone, email or whatsapp. |
Body:
| Field | Required | Description |
|---|---|---|
token | yes | The one-time code received by the merchant. |
device_fingerprint | no | Device fingerprint for fraud prevention. |
{ "token": "654321", "device_fingerprint": "abc123" }{ "token": "654321", "device_fingerprint": "abc123" }token and device_fingerprint is ignored.200 (channel ownership confirmed)4. Resolve data_grid
PUT /data-griddata_grid pendency. The body carries a pendencies
envelope; only data_grid is accepted, and each grid_info item is discriminated by its
attribute:{
"pendencies": [
{
"name": "data_grid",
"grid_info": [
{ "attribute": "email", "email": "teste@email.com" },
{ "attribute": "cell_phone", "cell_phone": "51992547923" }
]
}
]
}{
"pendencies": [
{
"name": "data_grid",
"grid_info": [
{ "attribute": "email", "email": "teste@email.com" },
{ "attribute": "cell_phone", "cell_phone": "51992547923" }
]
}
]
}pendenciesandgrid_infomust not be empty;namemust be exactlydata_grid.- The merchant must have an active
data_gridpendency (status pending); otherwise the request is rejected with422. - Only attributes in the attribute catalog are accepted; any other
attribute, an unknown field, an empty body, or a malformed value →
400.
204 (no content)5. Upload document
POST /upload-documentUploads a required document as Base64 content.
| Field | Required | Description |
|---|---|---|
document_type | yes | e.g. social_contract, identification_document, selfie. |
side | yes | Image side, e.g. front, back. |
file_type | yes | File format, e.g. pdf, jpg, png. |
file_base64 | yes | Base64-encoded file content (must be valid Base64). |
device_fingerprint | no | Device fingerprint. |
400.Response:
{
"storage_info": { "file_name": "799165-SOCIAL_CONTRACT-FRONT.PDF", "file_format": "PDF", "version": 1 },
"situation": { "status": "received", "status_update_date": "2026-07-02T20:08" }
}{
"storage_info": { "file_name": "799165-SOCIAL_CONTRACT-FRONT.PDF", "file_format": "PDF", "version": 1 },
"situation": { "status": "received", "status_update_date": "2026-07-02T20:08" }
}status_update_date is UTC truncated to the minute.422
("The submitted document already exists in this contract.").2006. Accept document
PUT /acceptance-documentAccepts a document or terms. The body carries a pendencies envelope:
{
"pendencies": [
{
"name": "privacy_policy",
"device_fingerprint": "abc123",
"situation": { "status": "finished" }
}
]
}{
"pendencies": [
{
"name": "privacy_policy",
"device_fingerprint": "abc123",
"situation": { "status": "finished" }
}
]
}name and situation.status are required; device_fingerprint is optional. Unknown fields
(including nested ones) are rejected with 400.The response flattens the first accepted pendency:
{
"name": "order_summary",
"file_name": "55074570-ORDER_SUMMARY.PDF",
"status": "finished",
"status_update_date": "2026-07-08T11:48"
}{
"name": "order_summary",
"file_name": "55074570-ORDER_SUMMARY.PDF",
"status": "finished",
"status_update_date": "2026-07-08T11:48"
}2007. Download document
GET /download-document/{documentType}documentType must be one of
terms_and_conditions or order_summary; any other value → 400 (rejected before any downstream
call).{ "document_type": "terms_and_conditions", "file_base64": "JVBERi0xLjQ=" }{ "document_type": "terms_and_conditions", "file_base64": "JVBERi0xLjQ=" }200data_grid attribute catalog
data_grid pendency is returned, grid_info lists the attributes that must be submitted.
The applicable set depends on the merchant's person type.Natural Person (PF)
country_of_birth, cell_phone, email, gross_monthly_income, net_worth,
residential_address, merchant_category_code, commercial_address, business_addressCompany (PJ)
merchant_category_code and business_address, plus the legal
representative's data:legal_representative.email, legal_representative.cell_phone,
legal_representative.country_of_birth, legal_representative.residential_address,
legal_representative.gross_monthly_income, legal_representative.net_worthValue rules per attribute
| Attribute | Value shape | Rule |
|---|---|---|
email / legal_representative.email | email | Valid email address, not blank. |
cell_phone / legal_representative.cell_phone | cell_phone | 10 to 13 digits. |
country_of_birth / legal_representative.country_of_birth | country | ISO 3166-1 alpha-2, uppercase (e.g. BR). |
residential_address, business_address, commercial_address (and legal_representative.residential_address) | address | See address fields below. |
merchant_category_code | merchant_category_code + economic_activity_classification_code, or acquirer_merchant_category_code | Provide the MCC pair (MCC = 4 digits, CNAE = 1–7 digits) or the acquirer MCC. |
gross_monthly_income / legal_representative.gross_monthly_income | gross_monthly_income | Whole integer amount in BRL (reais, not cents). |
net_worth / legal_representative.net_worth | net_worth | Whole integer amount in BRL (reais, not cents). |
street (required), number (blank is treated as "0"), district
(required), city, state, postal_code (required, digits only), country (required, ISO alpha-2).Example of an address item:
{
"attribute": "residential_address",
"address": {
"street": "RUA Y",
"number": "200",
"district": "MENINO DEUS",
"city": "PORTO ALEGRE",
"state": "RS",
"postal_code": "90110000",
"country": "BR"
}
}{
"attribute": "residential_address",
"address": {
"street": "RUA Y",
"number": "200",
"district": "MENINO DEUS",
"city": "PORTO ALEGRE",
"state": "RS",
"postal_code": "90110000",
"country": "BR"
}
}Business rules and constraints
- Only open pendencies can be resolved. Resolving
data_gridrequires an active (pending)data_gridpendency; otherwise422. - Selective exposure. Only the supported pendencies are returned; internal pendency types are never exposed.
grid_infois only returned while the pendency is pending. Attributes outside the catalog are discarded; if a pendingdata_gridcarries only unknown attributes, the API returns500.- Strict input. Partner request bodies reject unknown fields (
400) — the only exception is thetoken-validationbody, which ignores them. Empty bodies ({}/[]) are rejected, and a JSON object sent where an array is expected is also rejected. - Documents must contain valid Base64 content.
- Contact validation ordering. The verification code is always sent to the value already stored in the registration for that channel; the partner cannot override it.
- Person type is derived from the merchant's legal document: CPF →
natural_person, CNPJ →company. - No open pendencies returns an empty list.
- Anti-enumeration. An unknown or inaccessible merchant always results in
404, regardless of how the platform reports it internally. - Sensitive data must be transmitted over HTTPS, and all requests require authentication.
Data protection (masking)
Raw contact data is never returned to the partner:
| Where | Field | Example |
|---|---|---|
GET pendencies (email_validation) | data.value | teste@email.com → t***@email.com |
GET pendencies (cell_phone_validation) | data.value | 51992547923 → (51) 9****-7923 |
POST /token-request and POST /token-validation | email, cell_phone | same masking rules |
Masking rules: e-mail keeps the first character of the local part and the whole domain; phone keeps the area code and the last four digits. Values that cannot be masked (malformed) are omitted.
Error meanings
| HTTP | Meaning |
|---|---|
200 | Success |
202 | Accepted (validation code dispatched) |
204 | Success, no content returned |
400 | Invalid request (malformed body, unknown field, invalid value, unsupported channel/document type) |
401 | Missing or invalid authentication |
403 | Authenticated caller not allowed to access the resource |
404 | Merchant not found or not accessible by the partner (also returned for unknown routes) |
422 | Business rule violation (e.g. no active data_grid pendency, no contact value to send a code to) |
500 | Unexpected error, or a downstream service temporarily unavailable |
504 | Request timed out |
Error responses share a common shape:
{ "status_code": 422, "message": "No active data_grid pendency to resolve for this merchant.", "details": [] }{ "status_code": 422, "message": "No active data_grid pendency to resolve for this merchant.", "details": [] }details[], in snake_case:{
"status_code": 400,
"message": "Validation failed for one or more fields.",
"details": [ { "item": "pendencies[0].grid_info[0].email", "description": "email must be a valid email address" } ]
}{
"status_code": 400,
"message": "Validation failed for one or more fields.",
"details": [ { "item": "pendencies[0].grid_info[0].email", "description": "email must be a valid email address" } ]
}Two variations exist for document flows:
upload-document,acceptance-documentanddownload-documenterrors omit the emptydetailsarray, returning onlystatus_codeandmessage.- When the platform reports a field-level problem while accepting a document, the response is
{ "status_code": ..., "item": ..., "description": ... }.
Messages returned to the partner are always sanitized: internal identifiers, class names and downstream messages in Portuguese are never relayed.
On this page