neo-pays

Rebalances

Generated page, from the OpenAPI specification the gateway serves (GET /v1/openapi.json). Do not edit it by hand: it is rewritten on every build.

Method Path Description
GET /v1/rebalances List rebalances
POST /v1/rebalances Rebalance between your own platforms
GET /v1/rebalances/{id} Retrieve a rebalance
GET /v1/settlement-expectations List expected card settlements
POST /v1/settlement-expectations Announce the expected card settlement
GET /v1/rebalance-requests List rebalance requests
POST /v1/rebalance-requests Ask treasury for a rebalance
GET /v1/rebalance-requests/{id} Retrieve a rebalance request

GET /v1/rebalances

List rebalances

Same pagination as payments.

Parameters

Name In Required Description
page query no Page, starting at 1.
per_page query no Page size, 100 at most.

Responses

  • 200 — OK (OperationList)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)

POST /v1/rebalances

Rebalance between your own platforms

The single-account twin of the internal transfer: moves your own funds from one platform to another. Same conditions as the internal transfer.

Naming both corridors. Each takes either its id or its code — platform_id / platform_code for the source, destination_platform_id / destination_platform_code for the destination. They resolve independently: correcting the source does not paper over a wrong destination.

Naming the pots. platform_account_handle (source) and destination_platform_account_handle (destination) name one specific sub-account by its stable handle, as GET /v1/balances renders it. Absent = the corridor's primary pot, as before. An unknown handle is refused (422 unknown_platform_account), never folded onto the primary.

Parameters

Name In Required Description
Idempotency-Key header no An idempotency key specific to THIS operation. Replaying the same key with the same payload returns the original; replaying it with a different payload is refused (409).

Request body

Field Type Required Description
asset_id integer yes
amount_minor string yes Amount in MINOR UNITS, as a string. Never a floating-point number: both lose centimes. The asset's decimal count comes from GET /v1/assets.
country string yes ISO 3166-1 alpha-2
platform_id integer no The corridor's numeric id. ⚠️ NOT PORTABLE BETWEEN ENVIRONMENTS: platform ids are assigned by database insertion order, so an id read from sandbox may name a different rail in production. Prefer platform_code. Send either; sending both is accepted only when they agree, and refused with 422 platform_conflict when they do not.
platform_code string no The corridor's STABLE code — 'orange', 'wave', 'yas'. Case-insensitive. Means the same platform in every environment, which platform_id does not. Send this or platform_id.
destination_platform_id integer yes The platform being credited.
destination_platform_code string no The destination corridor's stable code. Resolves independently of platform_code, and refuses its own disagreement with destination_platform_id.
platform_account_handle string no Optionnel. Le nom stable du pot SOURCE sur sa plateforme (client_platform_accounts.handle). Absent = le pot principal.
destination_platform_account_handle string no Optionnel. Le nom stable du pot DESTINATION, ex. 'neo-card-card-programme'. Absent = le pot principal. Résolu indépendamment de la source.
client_ref string no
description string no

Responses

  • 201 — Rebalance created (Operation)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 409 — Clé d'idempotence rejouée avec une charge utile différente, ou aucun tarif de virement interne configuré pour cet actif et ce pays (pricing_unavailable) (Error)
  • 422 — Requête recevable mais refusée : champ manquant, corridor fermé, destination non payable (invalid_destination), pot nommé inconnu (unknown_platform_account), solde insuffisant (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)
  • 503 — platform_code momentarily unresolvable: the platform catalogue cannot be read (temporarily_unavailable). This is not a refusal — send the same request again after Retry-After (Error)

GET /v1/rebalances/{id}

Retrieve a rebalance

The same masked view as GET /v1/payments/{id}.

Parameters

Name In Required Description
id path yes Internal identifier, the operation's reference, or your own client_ref.

Responses

  • 200 — OK (Operation)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)

GET /v1/settlement-expectations

List expected card settlements

Your expectations by settlement date (inclusive bounds), newest first. Without to: today (UTC); without from: 30 days before to; 366 days at most.

Parameters

Name In Required Description
from query no Premier jour de règlement inclus, YYYY-MM-DD.
to query no Dernier jour de règlement inclus, YYYY-MM-DD.

Responses

  • 200 — OK (SettlementExpectationList)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 422 — Bornes mal formées ou intervalle trop long (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)

POST /v1/settlement-expectations

Announce the expected card settlement

Announces what the card scheme will debit, on a given day, from the named pot (e.g. the Ecobank card programme account, neo-card-card-programme). neo-pays keeps it awaiting_bank and reconciles the bank statement debit against it. No funds move.

Idempotent on the day and the pot. The same amount for the same (settlement_date, pot) returns the recorded expectation (200), whatever the idempotency key; a DIFFERENT amount is refused (409 expectation_conflict) and never replaces the first.

can_payout scope; a live key requires a live account.

Parameters

Name In Required Description
Idempotency-Key header no Conservée pour la traçabilité (ex. l'identifiant de votre outbox). L'idempotence porte sur (settlement_date, pot), pas sur cette clé.

Request body

Field Type Required Description
settlement_date string yes Le jour de règlement, YYYY-MM-DD.
asset_id integer yes
country string yes ISO 3166-1 alpha-2
platform_id integer no L'identifiant numérique de la plateforme (non portable). Envoyez celui-ci ou platform_code.
platform_code string no Le code stable de la plateforme, ex. 'sn-ecobank-senegal'.
platform_account_handle string no Optionnel. Le nom stable du pot, ex. 'neo-card-card-programme'. Absent = le pot principal ; inconnu = 422 unknown_platform_account.
amount_minor string yes Montant attendu en UNITÉS MINEURES, entier ≥ 0, en chaîne.
client_ref string no Votre référence, ex. la référence du rapport de règlement.

Responses

  • 200 — Rejeu : la même attente (même jour, même pot, même montant) était déjà enregistrée (SettlementExpectationResponse)
  • 201 — Attente enregistrée (SettlementExpectationResponse)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 409 — expectation_conflict : une attente existe déjà pour ce jour et ce pot avec un autre montant ; le corps porte aussi l'attente enregistrée sous data (Error)
  • 422 — Requête recevable mais refusée : champ manquant ou mal formé, plateforme inconnue, pot nommé inconnu (unknown_platform_account) (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)
  • 503 — platform_code momentarily unresolvable: the platform catalogue cannot be read (temporarily_unavailable). This is not a refusal — send the same request again after Retry-After (Error)

GET /v1/rebalance-requests

List rebalance requests

Your requests, newest first, in your key's mode (test or live). can_read_transactions scope.

Parameters

Name In Required Description
status query no Filtre sur le statut.
limit query no 1–200, défaut 50.

Responses

  • 200 — Les demandes (RebalanceRequestList)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)

POST /v1/rebalance-requests

Ask treasury for a rebalance

Asks neo-pays treasury to move your claims from one of your pots to another — including into a pot that POST /v1/rebalances refuses (invalid_destination), such as the product PI line or the card programme account. A request, not a move: it joins finance's four-eyes queue; once approved it executes as an ordinary rebalance, which then appears in GET /v1/rebalances (rebalance_id). Only pots on your allow-list can be requested (422 destination_not_allowed).

Idempotent on client_ref. The same body returns the recorded request (200); a different body is refused (409 rebalance_request_conflict).

Tracked by polling (no event): GET /v1/rebalance-requests/{id} every 5 minutes until the status is final (executed, failed, rejected, expired).

can_payout scope; a live key requires a live account.

Request body

Field Type Required Description
amount_minor string yes Montant en UNITÉS MINEURES, entier > 0, en chaîne.
asset_id integer yes
country string yes ISO 3166-1 alpha-2
source object yes
source.platform_code string no Le code stable de la plateforme, ex. 'neo-card' (ligne PI) ou 'sn-ecobank-senegal'.
source.platform_id integer no L'identifiant numérique (non portable). Envoyez celui-ci ou platform_code.
source.platform_account_handle string no Optionnel. Le nom stable du pot, ex. 'neo-card-card-programme'. Absent = le pot principal.
destination object yes
destination.platform_code string no Le code stable de la plateforme, ex. 'neo-card' (ligne PI) ou 'sn-ecobank-senegal'.
destination.platform_id integer no L'identifiant numérique (non portable). Envoyez celui-ci ou platform_code.
destination.platform_account_handle string no Optionnel. Le nom stable du pot, ex. 'neo-card-card-programme'. Absent = le pot principal.
reason string yes Pourquoi (≤ 500 caractères) — lu par la personne qui approuve.
client_ref string yes Votre référence (≤ 128), la clé d'idempotence.

Responses

  • 200 — Rejeu : la même demande était déjà enregistrée (RebalanceRequestResponse)
  • 201 — Demande enregistrée, en attente d'approbation (pending_approval) (RebalanceRequestResponse)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 409 — rebalance_request_conflict : ce client_ref nomme déjà une demande au corps différent (Error)
  • 422 — Refusée : champ manquant (invalid_request), plateforme ou pot inconnu (unknown_platform, unknown_platform_account), source = destination (same_pot), destination hors liste d'autorisation (destination_not_allowed) (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)
  • 503 — platform_code momentarily unresolvable: the platform catalogue cannot be read (temporarily_unavailable). This is not a refusal — send the same request again after Retry-After (Error)

GET /v1/rebalance-requests/{id}

Retrieve a rebalance request

The current status of one of your requests: pending_approval → approved → executed (with rebalance_id), or rejected, expired, failed (with failure_code). can_read_transactions scope.

Parameters

Name In Required Description
id path yes L'identifiant de la demande.

Responses

  • 200 — La demande (RebalanceRequestResponse)
  • 401 — API key missing or rejected (Error)
  • 403 — The key does not carry the required scope, or the account is not active (Error)
  • 404 — Aucune demande de ce compte (et de ce mode) sous cet identifiant (Error)
  • 429 — The key's request budget is exhausted (300/min) — honour Retry-After (Error)

Schemas

The shapes the operations above return.

OperationList

Field Type Description
data Operation[]
data[].id string The operation's public id. It is the one in the /v1/payments/{id} paths.
data[].ref string Our internal, readable reference. Distinct from the id: quote this one to support.
data[].client_ref string The reference you supplied at creation, returned unchanged.
data[].kind string payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which.
data[].status string The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail.
data[].outcome string pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on.
data[].asset_id integer The operation's asset, by its id (GET /v1/assets).
data[].amount_minor string The GROSS amount in minor units, as a string.
data[].fee_minor string The fee taken, in minor units.
data[].net_minor string The net in minor units: amount_minor less fee_minor.
data[].platform_id integer The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose.
data[].is_test boolean True for an operation created with a test key. No real money moves.
data[].payment_url string The hosted payment page, when the rail provides one. Absent until submission has succeeded.
data[].deeplink string The deep link into the rail's app, when it provides one.
data[].qrcode_url string The QR to show the payer, when the rail provides one.
data[].risk Risk The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block.
data[].risk.status string held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report.
data[].risk.case_ref string The operational case reference, to quote to support. Null when the hold is a compliance review.
data[].risk.case_kind string Accompanies case_ref, or nothing at all.
data[].risk.reason string The only free text this block carries, and it is identical for every hold.
data[].risk.signals object[] Product signals, advisory. Absent when there are none.
data[].risk.signals[].code string
data[].risk.signals[].detail_fr string
data[].amount_refunded_minor string Collections only: the sum of SUCCEEDED refunds, in minor units.
data[].amount_refund_pending_minor string Collections only: the sum of refunds IN PROGRESS, in minor units.
data[].amount_refundable_minor string Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…).
data[].refund_count integer Collections only: the number of refunds that did not fail.
data[].partial_refund_deadline string Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled.
page integer
per_page integer

Error

Field Type Description
error object
error.code string
error.message string

Operation

One money operation — collection, payout, refund, transfer or rebalance. The same object across all five families.

Field Type Description
id string The operation's public id. It is the one in the /v1/payments/{id} paths.
ref string Our internal, readable reference. Distinct from the id: quote this one to support.
client_ref string The reference you supplied at creation, returned unchanged.
kind string payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which.
status string The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail.
outcome string pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on.
asset_id integer The operation's asset, by its id (GET /v1/assets).
amount_minor string The GROSS amount in minor units, as a string.
fee_minor string The fee taken, in minor units.
net_minor string The net in minor units: amount_minor less fee_minor.
platform_id integer The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose.
is_test boolean True for an operation created with a test key. No real money moves.
payment_url string The hosted payment page, when the rail provides one. Absent until submission has succeeded.
deeplink string The deep link into the rail's app, when it provides one.
qrcode_url string The QR to show the payer, when the rail provides one.
risk Risk The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block.
risk.status string held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report.
risk.case_ref string The operational case reference, to quote to support. Null when the hold is a compliance review.
risk.case_kind string Accompanies case_ref, or nothing at all.
risk.reason string The only free text this block carries, and it is identical for every hold.
risk.signals object[] Product signals, advisory. Absent when there are none.
risk.signals[].code string
risk.signals[].detail_fr string
amount_refunded_minor string Collections only: the sum of SUCCEEDED refunds, in minor units.
amount_refund_pending_minor string Collections only: the sum of refunds IN PROGRESS, in minor units.
amount_refundable_minor string Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…).
refund_count integer Collections only: the number of refunds that did not fail.
partial_refund_deadline string Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled.

SettlementExpectationList

Field Type Description
data SettlementExpectation[]
data[].id string
data[].object string
data[].settlement_date string Le jour de règlement (YYYY-MM-DD).
data[].asset_id integer
data[].country string ISO 3166-1 alpha-2
data[].platform_id integer
data[].platform_code string Le code stable de la plateforme ; null s'il est inconnu.
data[].platform_account_id integer Le pot (0 = notre compte de plateforme).
data[].platform_account_handle string Le nom stable du pot ; null pour le pot principal non nommé.
data[].amount_minor string Montant attendu en unités mineures ; 0 = aucun règlement ce jour-là.
data[].client_ref string
data[].status string awaiting_bank à la création ; matched / unmatched après rapprochement.
data[].is_test boolean
data[].created_at string
data[].updated_at string
data[].match object Le débit du relevé bancaire rapproché de cette attente ; null tant que status n'est pas matched. Le rapprochement tolère un écart de date (± N jours ouvrés autour de settlement_date) et, si la finance l'a fixée, une tolérance de montant.
data[].match.statement_ref string La référence stable de la ligne du relevé (:<référence bancaire>).
data[].match.amount_minor string Ce que la banque a débité, en unités mineures — le montant du déchargement du pot ; peut différer de amount_minor dans la tolérance.
data[].match.date string La date de comptabilisation de la ligne bancaire (YYYY-MM-DD).
data[].match.matched_at string
data[].match.discharge_status string L'écriture qui sort le montant du pot : posted une fois comptabilisée ; refused si le pot ne le couvrait pas (reprise quotidienne).
data[].match.discharged_at string
data[].unmatched_reason string Pourquoi l'attente est unmatched (ex. no_bank_debit_within_window) ; null sinon.
data[].unmatched_at string

SettlementExpectationResponse

Field Type Description
data SettlementExpectation Le règlement carte ATTENDU pour un jour et un pot, tel que l'application l'annonce. Reste awaiting_bank jusqu'au rapprochement du débit correspondant sur le relevé bancaire.
data.id string
data.object string
data.settlement_date string Le jour de règlement (YYYY-MM-DD).
data.asset_id integer
data.country string ISO 3166-1 alpha-2
data.platform_id integer
data.platform_code string Le code stable de la plateforme ; null s'il est inconnu.
data.platform_account_id integer Le pot (0 = notre compte de plateforme).
data.platform_account_handle string Le nom stable du pot ; null pour le pot principal non nommé.
data.amount_minor string Montant attendu en unités mineures ; 0 = aucun règlement ce jour-là.
data.client_ref string
data.status string awaiting_bank à la création ; matched / unmatched après rapprochement.
data.is_test boolean
data.created_at string
data.updated_at string
data.match object Le débit du relevé bancaire rapproché de cette attente ; null tant que status n'est pas matched. Le rapprochement tolère un écart de date (± N jours ouvrés autour de settlement_date) et, si la finance l'a fixée, une tolérance de montant.
data.match.statement_ref string La référence stable de la ligne du relevé (:<référence bancaire>).
data.match.amount_minor string Ce que la banque a débité, en unités mineures — le montant du déchargement du pot ; peut différer de amount_minor dans la tolérance.
data.match.date string La date de comptabilisation de la ligne bancaire (YYYY-MM-DD).
data.match.matched_at string
data.match.discharge_status string L'écriture qui sort le montant du pot : posted une fois comptabilisée ; refused si le pot ne le couvrait pas (reprise quotidienne).
data.match.discharged_at string
data.unmatched_reason string Pourquoi l'attente est unmatched (ex. no_bank_debit_within_window) ; null sinon.
data.unmatched_at string

RebalanceRequestList

Field Type Description
data RebalanceRequest[]
data[].id string
data[].object string
data[].status string
data[].asset_id integer
data[].country string
data[].source object
data[].source.platform_id integer
data[].source.platform_code string
data[].source.platform_account_handle string
data[].destination object
data[].destination.platform_id integer
data[].destination.platform_code string
data[].destination.platform_account_handle string
data[].amount_minor string
data[].reason string
data[].client_ref string
data[].is_test boolean
data[].rebalance_id string Le rééquilibrage exécuté (GET /v1/rebalances), une fois executed.
data[].failure_code string
data[].created_at string
data[].updated_at string
data[].executed_at string

RebalanceRequestResponse

Field Type Description
data RebalanceRequest
data.id string
data.object string
data.status string
data.asset_id integer
data.country string
data.source object
data.source.platform_id integer
data.source.platform_code string
data.source.platform_account_handle string
data.destination object
data.destination.platform_id integer
data.destination.platform_code string
data.destination.platform_account_handle string
data.amount_minor string
data.reason string
data.client_ref string
data.is_test boolean
data.rebalance_id string Le rééquilibrage exécuté (GET /v1/rebalances), une fois executed.
data.failure_code string
data.created_at string
data.updated_at string
data.executed_at string