Business endpoints
Shared catalog of endpoints used by both PagaFactu and ZertiPay to manage flows, operations, PSD2 payments, beneficiary accounts and configurations.
This page groups the 18 common endpoints used by both PagaFactu and ZertiPay. The only product-specific endpoint is the PagaFactu flow creation (POST/flow/v1/flows/pagafactu), documented on the PagaFactu implementation page.
Common conventions
- Sandbox base URL:
https://api-sandbox.zertiban.com - Required headers on every call:
Authorization: Bearer {access_token}x-tenant-id: {businessUuid}
Flows
1. Create flow
Content-Type: multipart/form-data. The payload part must carry Content-Type: application/json; otherwise the server returns 400. For PagaFactu collections there is a dedicated POST/flow/v1/flows/pagafactu endpoint, documented on its implementation page.
curl -X POST https://api-sandbox.zertiban.com/flow/v1/flows \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}" \
-F 'payload={ "externalId": "...", "countryCode": "ES", "operations": [...] };type=application/json'Payload root:
| Field | Type | Req. | Description |
|---|---|---|---|
externalId | String | No | Your flow ID |
countryCode | String | Yes | ISO 3166 (e.g. "ES") |
additionalLanguage | String | No | ISO 639-1 |
operations | Array | Yes | 1 operation |
documents | Array | No | Attached PDFs (up to 10) |
labels | Array | No | Key-value labels |
Response (201):
| Field | Description |
|---|---|
uuid | Flow UUID |
externalId | Your externalId |
operations[i].uuid | Operation UUID |
operations[i].externalId | Your operation externalId |
operations[i].id | The local id you sent |
operations[i].url | Payment link for the payer |
2. List flows
# Flows completed in the last 7 days
curl "https://api-sandbox.zertiban.com/flow/v1/flows?q_status=COMPLETED&q_fromCreatedAt=2026-04-15T00:00:00Z&sort_by=STATUS_UPDATED_AT&sort_dir=DESC" \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
q_uuid | UUID | — | Filter by flow UUID |
q_externalId | String | — | Filter by externalId |
q_status | CSV | — | Flow statuses |
q_productLabelValue | CSV | — | Filter by product label value |
q_fromCreatedAt / q_toCreatedAt | ISO-8601 Instant | — | Creation range |
q_fromStatusUpdatedAt / q_toStatusUpdatedAt | ISO-8601 Instant | — | Status change range |
q_origin | Enum | — | Filter by flow origin: DIRECT (direct, no Partner/Agent) or COLLABORATOR (originated by a Partner/Agent). Case-insensitive. |
q_collaboratorUuid | UUID | — | Only flows originated by that specific Partner/Agent (exact match). |
q_collaboratorLegalName | String | — | Only flows whose Partner/Agent legal name contains the value (substring, case-insensitive). |
offset | int | 0 | Starting position |
limit | int | 10 | Results per page (max 100) |
sort_by | String | CREATED_AT | EXTERNAL_ID, STATUS, CREATED_AT, STATUS_UPDATED_AT |
sort_dir | String | DESC | ASC or DESC |
Incompatible combinations
q_origin=DIRECT cannot be combined with q_collaboratorUuid or q_collaboratorLegalName. The combination returns 400 INVALID_PARAMETER.
Response (200):
{
"total": 150,
"results": [
{
"uuid": "28ffd216-...",
"externalId": "COLLECTION-2026-001",
"status": "COMPLETED",
"createdAt": "2026-04-22T09:00:00Z",
"statusUpdatedAt": "2026-04-22T09:15:00Z",
"operationsCount": 1,
"labels": [{ "name": "order", "value": "12345" }],
"collaborator": {
"uuid": "f7c1a2b3-4d5e-6f70-8192-a3b4c5d6e7f8",
"legalName": "Perez Advisory Ltd"
}
},
{
"uuid": "3fa85f64-...",
"externalId": "COLLECTION-2026-002",
"status": "IN_PROGRESS",
"createdAt": "2026-04-23T10:00:00Z",
"statusUpdatedAt": "2026-04-23T10:05:00Z",
"operationsCount": 1,
"labels": [],
"collaborator": null
}
]
}The collaborator block identifies the Partner/Agent that originated the flow. It is null or absent when the flow was created directly by the organisation itself, with no Partner/Agent. It is an immutable snapshot captured at flow creation.
3. Flow detail
Returns the flow with a summary of its payment operations.
curl https://api-sandbox.zertiban.com/flow/v1/flows/{flowUuid} \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"Response (200):
{
"uuid": "28ffd216-5ee8-4e99-b1a9-511961e9c655",
"externalId": "COLLECTION-2026-001",
"status": "COMPLETED",
"countryCode": "ES",
"languageCode": "ES",
"createdAt": "2026-04-22T09:00:00Z",
"labels": [{ "name": "order", "value": "12345" }],
"paymentOperations": [
{
"uuid": "d1faff9e-...",
"externalId": "OP-2026-001",
"status": "COMPLETED",
"statusUpdatedAt": "2026-04-22T09:15:00Z",
"expiresAt": "2026-05-22T09:00:00Z",
"amount": 15075,
"currency": "EUR"
}
],
"collaborator": {
"uuid": "f7c1a2b3-4d5e-6f70-8192-a3b4c5d6e7f8",
"legalName": "Perez Advisory Ltd"
}
}| Field | Description |
|---|---|
status | Flow status (CREATED, IN_PROGRESS, COMPLETED, REJECTED, EXPIRED, CANCELLED) |
paymentOperations[i].amount | Amount in cents |
labels | Key-value labels sent when creating the flow |
collaborator | Partner/Agent that originated the flow, with uuid and legalName (legal name snapshotted at creation). null or absent ⇒ direct flow, no Partner/Agent. |
4. Flow status history
GET/flow/v1/flows/{flowUuid}/status-histories
curl https://api-sandbox.zertiban.com/flow/v1/flows/{flowUuid}/status-histories \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Response (200): Array sorted chronologically.
[
{ "previousStatus": null, "newStatus": "IN_PROGRESS", "changedAt": "2026-04-22T09:10:00Z" },
{ "previousStatus": "IN_PROGRESS", "newStatus": "COMPLETED", "changedAt": "2026-04-22T09:15:00Z" }
]5. Flow statistics
curl "https://api-sandbox.zertiban.com/flow/v1/flows/statistics?q_fromCreatedAt=2026-04-01T00:00:00Z" \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Accepts the same filters as GET/flow/v1/flows (without pagination).
Response (200):
{
"summary": { "totalFlows": 42 },
"groups": [
{ "key": "COMPLETED", "metrics": { "count": 38 } },
{ "key": "EXPIRED", "metrics": { "count": 3 } },
{ "key": "CANCELLED", "metrics": { "count": 1 } }
]
}Operations
6. List operations
# Completed operations of a specific flow
curl "https://api-sandbox.zertiban.com/flow/v1/operations?q_flowUuid={flowUuid}&q_status=COMPLETED" \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
q_operationUuid | UUID | — | Filter by operation UUID |
q_flowUuid | UUID | — | Filter by parent flow UUID |
q_externalId | String | — | Filter by operation externalId |
q_status | CSV | — | Statuses: CREATED, OPENED, COMPLETED, REJECTED, EXPIRED, CANCELLED |
q_type | CSV | — | Operation type (PAYMENT, SIGNATURE) |
q_invoiceExternalId | String | — | Filter by invoice externalId |
q_fromCreatedAt | ISO-8601 Instant | — | Created from |
q_toCreatedAt | ISO-8601 Instant | — | Created to |
q_fromStatusUpdatedAt | ISO-8601 Instant | — | Last status change from |
q_toStatusUpdatedAt | ISO-8601 Instant | — | Last status change to |
q_amountFrom | Long | — | Minimum amount (cents) |
q_amountTo | Long | — | Maximum amount (cents) |
q_origin | Enum | — | Filter by the owning flow's origin: DIRECT (no Partner/Agent) or COLLABORATOR (originated by a Partner/Agent). Case-insensitive. |
q_collaboratorUuid | UUID | — | Only operations whose owning flow was originated by that specific Partner/Agent (exact match). |
q_collaboratorLegalName | String | — | Only operations whose owning flow's Partner/Agent legal name contains the value (substring, case-insensitive). |
offset | int | 0 | Starting position |
limit | int | 10 | Results per page (max 100) |
sort_by | String | CREATED_AT | EXTERNAL_ID, STATUS, CREATED_AT, STATUS_UPDATED_AT |
sort_dir | String | DESC | ASC or DESC |
Incompatible combinations
q_origin=DIRECT cannot be combined with q_collaboratorUuid or q_collaboratorLegalName. The combination returns 400 INVALID_PARAMETER.
Response (200):
{
"total": 42,
"results": [
{
"uuid": "d1faff9e-...",
"externalId": "OP-2026-001",
"status": "COMPLETED",
"type": "PAYMENT",
"createdAt": "2026-04-22T09:00:00Z",
"statusUpdatedAt": "2026-04-22T09:15:00Z",
"flow": {
"uuid": "28ffd216-...",
"collaborator": {
"uuid": "f7c1a2b3-4d5e-6f70-8192-a3b4c5d6e7f8",
"legalName": "Perez Advisory Ltd"
}
}
},
{
"uuid": "a2b3c4d5-...",
"externalId": null,
"status": "CREATED",
"type": "SIGNATURE",
"createdAt": "2026-04-23T08:22:00Z",
"statusUpdatedAt": null,
"flow": {
"uuid": "3fa85f64-...",
"collaborator": null
}
}
]
}The Partner/Agent attribution is inherited from the owning flow and exposed under flow.collaborator in each item. null or absent ⇒ operation belongs to a direct flow.
7. Operation detail
Returns all operation data, including PSD2 payment details and the paymentUuid you need to fetch the payment detail once completed.
curl https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid} \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"Response (200):
{
"uuid": "d1faff9e-bb8b-47bd-8b47-4f20f1a7912b",
"externalId": "OP-2026-001",
"flowUuid": "28ffd216-5ee8-4e99-b1a9-511961e9c655",
"configurationUuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "COMPLETED",
"type": "PAYMENT",
"expirationOffset": "P30D",
"expiresAt": "2026-05-22T09:00:00Z",
"createdAt": "2026-04-22T09:00:00Z",
"synchronous": true,
"payment": {
"paymentUuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"amount": 15075,
"currency": "EUR",
"concept": "Collection 2026-001",
"types": ["PSD2_PAYMENT"],
"psd2Payment": {
"type": "SINGLE_PAYMENT",
"product": "SEPA_CREDIT_TRANSFER",
"creditorAccount": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
},
"subject": { "name": "Ana", "lastName": "Martinez", "email": "[email protected]" }
},
"flow": {
"uuid": "28ffd216-5ee8-4e99-b1a9-511961e9c655",
"collaborator": {
"uuid": "f7c1a2b3-4d5e-6f70-8192-a3b4c5d6e7f8",
"legalName": "Perez Advisory Ltd"
}
}
}| Field | Description |
|---|---|
payment.paymentUuid | PSD2 payment UUID. Available once status is COMPLETED. Use it to call GET/payment/v1/payments/{uuid}. |
payment.amount | Amount in cents. |
payment.subject | Debtor data as sent when creating the flow. |
expiresAt | Operation expiration date. |
flow.collaborator | Owning flow's Partner/Agent, with uuid and legalName (legal name snapshotted at creation). Absent or null when the operation belongs to a direct flow. |
8. Quick operation status
GET/flow/v1/operations/{operationUuid}/status
Returns the operation's current status with a minimal payload. Ideal for frequent polling when you don't need the full object.
curl https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid}/status \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"Response (200):
{
"status": "COMPLETED",
"actionCode": "INITIATED",
"final": true
}| Field | Type | Description |
|---|---|---|
status | String | Current status: CREATED, OPENED, COMPLETED, REJECTED, EXPIRED, CANCELLED. |
actionCode | String | Platform-internal action code. |
final | boolean | true when the state is terminal (no further transitions possible). |
9. Operation status history
GET/flow/v1/operations/{uuid}/status-histories
Returns the full sequence of state transitions, useful for auditing the lifecycle of a collection.
curl https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid}/status-histories \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Response (200): Array sorted chronologically.
[
{ "previousStatus": null, "newStatus": "CREATED", "changedAt": "2026-04-22T09:00:00Z" },
{ "previousStatus": "CREATED", "newStatus": "OPENED", "changedAt": "2026-04-22T09:10:00Z" },
{ "previousStatus": "OPENED", "newStatus": "COMPLETED", "changedAt": "2026-04-22T09:15:00Z" }
]| Field | Type | Description |
|---|---|---|
previousStatus | String | Previous status (null for the initial state). |
newStatus | String | New status. |
changedAt | Instant | Moment of the transition. |
10. Operation statistics
GET/flow/v1/operations/statistics
Returns aggregated metrics: total operations and amount totals, with the same filters as the listing.
# Total collected and per-status breakdown for the last month
curl "https://api-sandbox.zertiban.com/flow/v1/operations/statistics?q_fromCreatedAt=2026-03-22T00:00:00Z" \
-H "Authorization: Bearer {access_token}" -H "x-tenant-id: {businessUuid}"Accepts the same filter query parameters as GET/flow/v1/operations (without offset, limit, sort_by, sort_dir).
Response (200):
{
"summary": { "total": 42 },
"groups": [
{ "key": "COMPLETED", "metrics": { "count": 38, "amount": 578450 } },
{ "key": "EXPIRED", "metrics": { "count": 3, "amount": 45000 } },
{ "key": "CANCELLED", "metrics": { "count": 1, "amount": 15075 } }
]
}| Field | Description |
|---|---|
summary.total | Total operations matching the filters. |
groups[i].key | Grouper value (operation status). |
groups[i].metrics.count | Number of operations in this group. |
groups[i].metrics.amount | Sum of amounts in cents in this group. |
11. Cancel operation
PUT/flow/v1/operations/{operationUuid}/cancel
Cancels an operation that has not yet reached a final state.
curl -X PUT https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid}/cancel \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"No body in the request.
Successful response: 204 No Content
| Code | Cause |
|---|---|
409 | The operation is already in a final state (COMPLETED, REJECTED, EXPIRED, CANCELLED). |
409 | The operation is in OPENED and the payer has a payment in progress (pending transaction). |
If the flow had this operation as the only active one, the flow will also become CANCELLED.
12. Extend operation expiration
PATCH/flow/v1/operations/{operationUuid}/expiration
Recomputes the operation's expiration by adding the given duration to the call time (expiresAt = now + duration).
curl -X PATCH https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid}/expiration \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}" \
-H "Content-Type: application/json" \
-d '{ "duration": "P7D" }'Request body:
| Field | Type | Description |
|---|---|---|
duration | String | ISO 8601 duration in days only (e.g. "P7D" = 7 days, "P30D" = 30 days). Only the D designator is supported. |
Successful response: 204 No Content
Restrictions:
- The operation must be in a non-final state (CREATED or OPENED).
- Minimum duration is 1 day (
P1D). - The
durationfield only accepts the day designator (D). Hours (H) and minutes are not allowed.
13. Download attached payment document
GET/flow/v1/operations/{operationUuid}/payment-documents/{paymentDocumentUuid}/content
Downloads the binary content of a PDF document attached when creating the flow. The documentUuid comes from the payment.documents array in the operation detail.
curl https://api-sandbox.zertiban.com/flow/v1/operations/{operationUuid}/payment-documents/{documentUuid}/content \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}" \
-o document.pdfResponse: application/pdf binary with the header Content-Disposition: attachment; filename="<file-name>". If no name is available, the server uses payment-document.pdf.
PSD2 payment
14. PSD2 payment detail
GET/payment/v1/payments/{uuid}
The paymentUuid is available in GET/flow/v1/operations/{uuid} → field payment.paymentUuid, once the operation reaches the COMPLETED state.
curl https://api-sandbox.zertiban.com/payment/v1/payments/{paymentUuid} \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"Response (200):
{
"psd2Payment": {
"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"status": { "code": "ACSC", "status": "AcceptedSettlementCompleted" },
"instructedAmount": { "amount": 15075, "currency": "EUR" },
"remittanceInformationUnstructured": "Collection 2026-001",
"executionDate": "2026-04-22T09:14:00Z",
"requestedExecutionDate": null,
"bankPaymentId": "BANKA12345678",
"creditorAccount": {
"ownerName": "My Company Ltd.",
"accountNumber": "ES91210004183401234567",
"bic": "CAIXESBBXXX",
"country": "ES",
"type": "IBAN"
},
"debtorAccount": {
"uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"accountNumber": "ES8020484097908424975543",
"type": "IBAN",
"currency": "EUR",
"psuName": "Ana Martinez",
"ownerName": "Ana Martinez",
"bic": "BBVAESMMXXX"
}
},
"collaborator": {
"uuid": "f7c1a2b3-4d5e-6f70-8192-a3b4c5d6e7f8"
}
}| Field | Description |
|---|---|
psd2Payment.status.code | ISO 20022 code of the payment status (e.g. ACSC = settled). |
psd2Payment.instructedAmount | Exact amount that was moved. |
psd2Payment.remittanceInformationUnstructured | Payment concept / reference. |
psd2Payment.executionDate | When the bank processed the payment. |
psd2Payment.requestedExecutionDate | Only present for scheduled payments (FUTURE_PAYMENT). |
psd2Payment.bankPaymentId | Bank-assigned payment identifier. |
psd2Payment.creditorAccount | Beneficiary account that received the money. |
psd2Payment.debtorAccount | Payer account that issued the transfer. |
collaborator.uuid | UUID of the Partner/Agent that originated the flow this payment belongs to. Attribution inherited immutably at payment creation. Unlike flow-service, the legal name is not exposed here; if you need it, fetch it from the flow or operation detail. The collaborator block is null or absent for payments originated directly. |
Beneficiary accounts
Detailed field and filter documentation in Beneficiary accounts.
15. List beneficiary accounts
GET/business-creditor-account/v1/business-creditor-accounts
curl "https://api-sandbox.zertiban.com/business-creditor-account/v1/business-creditor-accounts?offset=0&limit=10" \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"| Parameter | Type | Default | Description |
|---|---|---|---|
offset | int | 0 | Starting position |
limit | int | — | Results per page |
q_status | enum (ACTIVE / DISABLED) | — | Filter by status. No value returns all. |
q_isDefault | boolean | — | Filter by whether it's the default account. |
16. Beneficiary account detail
GET/business-creditor-account/v1/business-creditor-accounts/{uuid}
curl "https://api-sandbox.zertiban.com/business-creditor-account/v1/business-creditor-accounts/{uuid}" \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"| Field | Type | Description |
|---|---|---|
uuid | UUID | creditorAccountUuid to use when creating flows |
accountNumber | String | Account number (masked) |
type | String | Account type. Possible value: IBAN |
alias | String | Identifying name |
status | String | ACTIVE or DISABLED. Only ACTIVE accept payments. |
isDefault | Boolean | Whether it's the organisation's default beneficiary account |
aspsp.commercialName | String | Bank commercial name |
Flow configurations
Detailed field and filter documentation in Flow configuration.
17. List configurations
GET/flow-customization/v1/configurations
curl "https://api-sandbox.zertiban.com/flow-customization/v1/configurations?offset=0&limit=10" \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"18. Configuration detail
GET/flow-customization/v1/configurations/{configurationUuid}
curl https://api-sandbox.zertiban.com/flow-customization/v1/configurations/{configurationUuid} \
-H "Authorization: Bearer {access_token}" \
-H "x-tenant-id: {businessUuid}"Summary table
Sandbox base URL: https://api-sandbox.zertiban.com
Common errors
| Code | Typical cause | Solution |
|---|---|---|
400 | Invalid payload: missing field, wrong format, mistyped parameter | Review the validation in the reference section |
401 | Expired token or invalid credentials | Request a new token with Basic Auth |
403 | Wrong x-tenant-id or insufficient credential permissions | Verify businessUuid and credential permissions |
404 | Configuration, account, operation, flow or payment UUID not found | Verify with the GET endpoints |
409 | State conflict (cancel finished operation, inactive configuration) | Check the current status before the action |