{"components":{"schemas":{"DashboardSummaryOut":{"additionalProperties":false,"description":"A summary of your money movements: what actually moved, how many transactions are in each state, and how much is still uncertain.","properties":{"counts":{"additionalProperties":{"type":"integer"},"title":"Counts","type":"object"},"open_indeterminate":{"$ref":"#/components/schemas/MoneyOut"},"open_indeterminate_count":{"title":"Open Indeterminate Count","type":"integer"},"volume":{"$ref":"#/components/schemas/MoneyOut"}},"required":["volume","counts","open_indeterminate","open_indeterminate_count"],"title":"DashboardSummaryOut","type":"object"},"DashboardTransactionOut":{"additionalProperties":false,"description":"One money movement on this account: what it was, what it cost you, and where it got to.","properties":{"charged":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"created_at":{"format":"date-time","title":"Created At","type":"string"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key"},"product":{"title":"Product","type":"string"},"reference":{"title":"Reference","type":"string"},"state":{"title":"State","type":"string"},"your_reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Your Reference"}},"required":["reference","product","state","created_at"],"title":"DashboardTransactionOut","type":"object"},"ErrorOut":{"additionalProperties":false,"description":"The one error shape. Every failure looks like this.\n\n`correlation_id` is what support quotes to find the log line that holds\nthe detail deliberately kept out of this response.","properties":{"code":{"title":"Code","type":"string"},"correlation_id":{"title":"Correlation Id","type":"string"},"details":{"additionalProperties":true,"title":"Details","type":"object"},"message":{"title":"Message","type":"string"},"retry_after_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retry After Seconds"}},"required":["code","message","correlation_id"],"title":"ErrorOut","type":"object"},"MoneyOut":{"additionalProperties":false,"properties":{"amount_minor":{"examples":["450000"],"title":"Amount Minor","type":"string"},"currency":{"examples":["NGN"],"maxLength":3,"minLength":3,"title":"Currency","type":"string"}},"required":["amount_minor","currency"],"title":"MoneyOut","type":"object"},"PartnerAgreementIn":{"additionalProperties":false,"description":"Sign the API agreement.\n\nYour legal name and liaison email are taken from your account, not from this request. The remaining fields are what you are declaring.\n\nSigning is once per version. If we publish an amendment you will be asked to sign the new one before further live keys are issued.\n\nSend back the `version` you were shown. If the agreement has been updated since you read it, we return 409 rather than record a signature against text you did not see.","properties":{"agreement_version":{"maxLength":64,"minLength":1,"title":"Agreement Version","type":"string"},"country":{"maxLength":100,"minLength":2,"title":"Country","type":"string"},"nature_of_business":{"maxLength":500,"minLength":3,"title":"Nature Of Business","type":"string"},"registered_address":{"maxLength":500,"minLength":5,"title":"Registered Address","type":"string"},"signatory_name":{"maxLength":200,"minLength":2,"title":"Signatory Name","type":"string"},"signatory_role":{"maxLength":200,"minLength":2,"title":"Signatory Role","type":"string"}},"required":["agreement_version","signatory_name","signatory_role","nature_of_business","country","registered_address"],"title":"PartnerAgreementIn","type":"object"},"PartnerAgreementOut":{"additionalProperties":false,"description":"The API agreement: its current text, what we have filled in for you, and whether you have signed it.\n\n`available` is false while we are finalising the document. Nothing can be signed until it is true, and live API keys are issued only after signing.","properties":{"available":{"title":"Available","type":"boolean"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The agreement text, as a template. It contains `{{field}}` slots which are filled in from the signing form; they are placeholders, not a rendering fault. Null while no version is published.","title":"Body"},"legal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Name"},"liaison_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Liaison Email"},"signable":{"default":false,"title":"Signable","type":"boolean"},"signatory_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signatory Name"},"signed":{"default":false,"title":"Signed","type":"boolean"},"signed_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Signed At"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"}},"required":["available"],"title":"PartnerAgreementOut","type":"object"},"PartnerAgreementStatusOut":{"additionalProperties":false,"description":"Whether this account has signed the current API agreement.\n\nLive API keys are issued only to an account that has signed the version in force. If we publish an amendment, `signed` returns to false until it is signed again, and no further live keys are issued until then. Existing keys keep working.\n\nSigning happens in the dashboard. This endpoint is here so your own systems can check the state without a person looking.","properties":{"current_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Version"},"signed":{"title":"Signed","type":"boolean"},"signed_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Signed At"}},"required":["signed"],"title":"PartnerAgreementStatusOut","type":"object"},"PartnerBalanceOut":{"additionalProperties":false,"properties":{"balance":{"$ref":"#/components/schemas/MoneyOut"},"held":{"$ref":"#/components/schemas/MoneyOut"},"min_balance":{"$ref":"#/components/schemas/MoneyOut"},"next_clears_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Next Clears At"},"partner":{"title":"Partner","type":"string"}},"required":["partner","balance","min_balance","held","next_clears_at"],"title":"PartnerBalanceOut","type":"object"},"PartnerBankOut":{"additionalProperties":false,"description":"A bank you can send a payout to. Take `code` from this list and send it back unchanged — it is not always numeric.","properties":{"code":{"examples":["044"],"title":"Code","type":"string"},"name":{"examples":["Access Bank"],"title":"Name","type":"string"}},"required":["code","name"],"title":"PartnerBankOut","type":"object"},"PartnerBillerOut":{"additionalProperties":false,"description":"A biller we can buy a product from.\n\n`code` is opaque: send it back unchanged, do not parse it, and do not hardcode a value you saw once.","properties":{"code":{"title":"Code","type":"string"},"name":{"title":"Name","type":"string"}},"required":["code","name"],"title":"PartnerBillerOut","type":"object"},"PartnerEnquiryIn":{"additionalProperties":false,"description":"Ask who owns a bank account, before sending anything to it.","properties":{"account_number":{"maxLength":10,"minLength":10,"pattern":"^\\d{10}$","title":"Account Number","type":"string"},"bank_code":{"maxLength":6,"minLength":3,"title":"Bank Code","type":"string"}},"required":["account_number","bank_code"],"title":"PartnerEnquiryIn","type":"object"},"PartnerEnquiryOut":{"additionalProperties":false,"description":"The account holder's name as the bank spells it, or a reason we could not check.\n\nShow the name to whoever is sending the money and have them confirm it. We re-run this check when you send, and use the bank's spelling rather than anything you pass us.","properties":{"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"required":["account_name","message"],"title":"PartnerEnquiryOut","type":"object"},"PartnerForgotIn":{"additionalProperties":false,"description":"Start a password reset for a dashboard account.\n\nAlways succeeds, whether or not the address has an account. If it does, a code is emailed to it.","properties":{"email":{"maxLength":320,"minLength":3,"title":"Email","type":"string"}},"required":["email"],"title":"PartnerForgotIn","type":"object"},"PartnerForgotOut":{"additionalProperties":false,"description":"A reset was started. Send the code and `challenge_token` to the reset endpoint.\n\n`masked_target` is built from the address you sent, not from an account, so it tells you nothing about whether one exists.","properties":{"challenge_token":{"title":"Challenge Token","type":"string"},"masked_target":{"title":"Masked Target","type":"string"},"requires_code":{"default":true,"title":"Requires Code","type":"boolean"}},"required":["masked_target","challenge_token"],"title":"PartnerForgotOut","type":"object"},"PartnerFundingIn":{"additionalProperties":false,"description":"Start a top-up of your prepaid balance.\n\nReturns a `checkout_url` to send the payer to. **Nothing is credited when you call this** — your balance moves only once the payment is confirmed, which is normally seconds later and is why `GET /balance` is the thing to poll rather than this response.\n\nRecently added money is held briefly before it can fund a payout; the balance read reports how much and until when.","properties":{"amount_minor":{"exclusiveMinimum":0,"title":"Amount Minor","type":"integer"},"currency":{"default":"NGN","maxLength":3,"minLength":3,"title":"Currency","type":"string"}},"required":["amount_minor"],"title":"PartnerFundingIn","type":"object"},"PartnerFundingOut":{"additionalProperties":false,"description":"A started top-up. Send the payer to `checkout_url`.\n\nThis is **not** a confirmation of payment. Your balance changes when the payment is confirmed, not when this is returned, so do not credit anything of your own on the strength of it.\n\n`reference` is ours and is what appears on your balance history. Quote it to us if a payment goes missing.","properties":{"amount":{"$ref":"#/components/schemas/MoneyOut"},"checkout_url":{"title":"Checkout Url","type":"string"},"reference":{"title":"Reference","type":"string"}},"required":["reference","amount","checkout_url"],"title":"PartnerFundingOut","type":"object"},"PartnerLoginIn":{"additionalProperties":false,"description":"Sign in with a member's email address and password.","properties":{"email":{"maxLength":320,"minLength":3,"title":"Email","type":"string"},"password":{"maxLength":1024,"minLength":1,"title":"Password","type":"string"}},"required":["email","password"],"title":"PartnerLoginIn","type":"object"},"PartnerMemberOut":{"additionalProperties":false,"description":"The signed-in member.","properties":{"email":{"title":"Email","type":"string"},"full_name":{"title":"Full Name","type":"string"},"id":{"format":"uuid","title":"Id","type":"string"},"role":{"enum":["owner","member"],"title":"Role","type":"string"}},"required":["id","email","full_name","role"],"title":"PartnerMemberOut","type":"object"},"PartnerPackageOut":{"additionalProperties":false,"description":"Something a biller sells.\n\n`amount` is null when the biller prices it at purchase time — a prepaid meter has no fixed price. `requires_validation` means the customer identifier must be checked before buying.","properties":{"amount":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"code":{"title":"Code","type":"string"},"name":{"title":"Name","type":"string"},"requires_validation":{"title":"Requires Validation","type":"boolean"}},"required":["code","name","requires_validation"],"title":"PartnerPackageOut","type":"object"},"PartnerPayoutIn":{"additionalProperties":false,"description":"Send money to a Nigerian bank account.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than sending a second time, and we reuse your reference with the rail so it deduplicates too.\n\nWe confirm the account holder's name with the bank ourselves and send to the name the bank gives, so there is no name field to pass.","properties":{"account_number":{"maxLength":10,"minLength":10,"pattern":"^\\d{10}$","title":"Account Number","type":"string"},"amount_minor":{"exclusiveMinimum":0,"title":"Amount Minor","type":"integer"},"bank_code":{"maxLength":6,"minLength":3,"title":"Bank Code","type":"string"},"your_reference":{"anyOf":[{"maxLength":128,"type":"string"},{"type":"null"}],"title":"Your Reference"}},"required":["amount_minor","account_number","bank_code"],"title":"PartnerPayoutIn","type":"object"},"PartnerPayoutOut":{"additionalProperties":false,"description":"The payout, and the state it is in.\n\n`succeeded` means the rail accepted it. `pending` means the rail is still working and we will resolve it. `indeterminate` means the rail did not answer clearly: the money may or may not have moved, we are asking, and you must NOT retry or refund your user on it.\n\n`charged` is what came out of your balance — the amount plus our fee. `amount` is what the beneficiary receives.","properties":{"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"amount":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"charged":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"fee":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"reference":{"title":"Reference","type":"string"},"state":{"enum":["succeeded","pending","indeterminate","failed"],"title":"State","type":"string"},"your_reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Your Reference"}},"required":["reference","state"],"title":"PartnerPayoutOut","type":"object"},"PartnerPurchaseIn":{"additionalProperties":false,"description":"What to buy for one of your customers. The product itself is the path you post to.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\nTake `biller_code` and `package_code` from the catalogue and send them back unchanged. Airtime needs neither.","properties":{"amount_minor":{"exclusiveMinimum":0,"title":"Amount Minor","type":"integer"},"biller_code":{"anyOf":[{"maxLength":64,"type":"string"},{"type":"null"}],"title":"Biller Code"},"customer_reference":{"maxLength":64,"minLength":3,"title":"Customer Reference","type":"string"},"package_code":{"anyOf":[{"maxLength":64,"type":"string"},{"type":"null"}],"title":"Package Code"},"subject_id":{"anyOf":[{"format":"uuid","type":"string"},{"type":"null"}],"title":"Subject Id"},"your_reference":{"anyOf":[{"maxLength":128,"type":"string"},{"type":"null"}],"title":"Your Reference"}},"required":["amount_minor","customer_reference"],"title":"PartnerPurchaseIn","type":"object"},"PartnerPurchaseOut":{"additionalProperties":false,"description":"The purchase, the state it is in, and what was delivered.\n\n`data` carries what your customer bought — a meter token, a PIN reference. It is empty until the purchase succeeds.\n\n`indeterminate` means we do not yet know whether the biller delivered. Do not retry and do not refund your customer on it.","properties":{"amount":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"charged":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"What your customer bought, such as a meter token or a PIN reference. An empty object until the purchase succeeds. `null` on the state read, which does not carry the delivery: it is returned on the purchase response and on a replay of that response, and it will be in the webhook once we are sending those.","title":"Data"},"fee":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"product":{"title":"Product","type":"string"},"reference":{"title":"Reference","type":"string"},"state":{"title":"State","type":"string"},"your_reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Your Reference"}},"required":["reference","product","state"],"title":"PartnerPurchaseOut","type":"object"},"PartnerResetIn":{"additionalProperties":false,"description":"Finish a password reset with the code that was emailed.\n\nSigns every dashboard session out, including this one. Your API keys are not affected.","properties":{"challenge_token":{"maxLength":256,"minLength":10,"title":"Challenge Token","type":"string"},"code":{"maxLength":10,"minLength":4,"title":"Code","type":"string"},"new_password":{"maxLength":256,"minLength":12,"title":"New Password","type":"string"}},"required":["challenge_token","code","new_password"],"title":"PartnerResetIn","type":"object"},"PartnerResetOut":{"additionalProperties":false,"description":"The password was changed. Sign in again with the new one.","properties":{"sessions_ended":{"title":"Sessions Ended","type":"integer"}},"required":["sessions_ended"],"title":"PartnerResetOut","type":"object"},"PartnerSessionOut":{"additionalProperties":false,"description":"The member and account for the current session, and when the session expires. The session itself travels as a cookie and is not part of this body.","properties":{"expires_at":{"format":"date-time","title":"Expires At","type":"string"},"member":{"$ref":"#/components/schemas/PartnerMemberOut"},"partner":{"$ref":"#/components/schemas/PartnerSummaryOut"}},"required":["member","partner","expires_at"],"title":"PartnerSessionOut","type":"object"},"PartnerSignupIn":{"additionalProperties":false,"description":"Create a VertexBridge account and its first member. The company name becomes your account's identifier; you do not choose it directly.","properties":{"company_name":{"maxLength":200,"minLength":2,"title":"Company Name","type":"string"},"email":{"maxLength":320,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email","type":"string"},"full_name":{"maxLength":200,"minLength":2,"title":"Full Name","type":"string"},"password":{"maxLength":1024,"minLength":12,"title":"Password","type":"string"}},"required":["company_name","full_name","email","password"],"title":"PartnerSignupIn","type":"object"},"PartnerSummaryOut":{"additionalProperties":false,"description":"The account the member belongs to. `status` is `pending` until we have verified your business; a pending account can use the sandbox and hold test API keys.","properties":{"id":{"format":"uuid","title":"Id","type":"string"},"name":{"title":"Name","type":"string"},"slug":{"title":"Slug","type":"string"},"status":{"enum":["pending","active","suspended","closed"],"title":"Status","type":"string"}},"required":["id","slug","name","status"],"title":"PartnerSummaryOut","type":"object"},"PartnerTransactionOut":{"additionalProperties":false,"description":"One money movement on your account: what it was, what it cost you, the state it is in now, and your own reference for it if you sent one.","properties":{"charged":{"anyOf":[{"$ref":"#/components/schemas/MoneyOut"},{"type":"null"}]},"created_at":{"format":"date-time","title":"Created At","type":"string"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The `Idempotency-Key` you sent when you created this. Use it to answer whether a retry of yours created a second transaction or replayed the first.","title":"Idempotency Key"},"product":{"title":"Product","type":"string"},"reference":{"title":"Reference","type":"string"},"state":{"title":"State","type":"string"},"your_reference":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The reference you sent when you created this, if you sent one. We store it so you can find a transaction by an identifier you already hold, and you can filter this list by it.","title":"Your Reference"}},"required":["reference","product","state","created_at"],"title":"PartnerTransactionOut","type":"object"},"PartnerWhoamiOut":{"additionalProperties":false,"properties":{"allowed_products":{"items":{"type":"string"},"title":"Allowed Products","type":"array"},"name":{"title":"Name","type":"string"},"partner":{"title":"Partner","type":"string"},"rate_limit_per_minute":{"title":"Rate Limit Per Minute","type":"integer"},"scopes":{"items":{"type":"string"},"title":"Scopes","type":"array"},"status":{"enum":["pending","active","suspended","closed"],"title":"Status","type":"string"}},"required":["partner","name","status","allowed_products","scopes","rate_limit_per_minute"],"title":"PartnerWhoamiOut","type":"object"},"WebhookDeliveryOut":{"additionalProperties":false,"properties":{"attempts":{"title":"Attempts","type":"integer"},"created_at":{"format":"date-time","title":"Created At","type":"string"},"delivered_at":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"title":"Delivered At"},"event_id":{"format":"uuid","title":"Event Id","type":"string"},"event_type":{"title":"Event Type","type":"string"},"id":{"format":"uuid","title":"Id","type":"string"},"last_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status Code"},"status":{"enum":["pending","delivered","failed","abandoned"],"title":"Status","type":"string"}},"required":["id","event_id","event_type","status","attempts","last_status_code","created_at","delivered_at"],"title":"WebhookDeliveryOut","type":"object"},"WebhookReplayOut":{"additionalProperties":false,"properties":{"delivery_id":{"format":"uuid","title":"Delivery Id","type":"string"},"status":{"const":"pending","title":"Status","type":"string"}},"required":["delivery_id","status"],"title":"WebhookReplayOut","type":"object"},"WebhookSigningOut":{"additionalProperties":false,"description":"The verification recipe, served from the sender's own constants.","properties":{"algorithm":{"title":"Algorithm","type":"string"},"event_id_header":{"title":"Event Id Header","type":"string"},"notes":{"items":{"type":"string"},"title":"Notes","type":"array"},"replay_window_seconds":{"title":"Replay Window Seconds","type":"integer"},"signature_header":{"title":"Signature Header","type":"string"},"signed_material":{"title":"Signed Material","type":"string"},"timestamp_header":{"title":"Timestamp Header","type":"string"}},"required":["algorithm","signed_material","signature_header","timestamp_header","event_id_header","replay_window_seconds","notes"],"title":"WebhookSigningOut","type":"object"}}},"info":{"title":"VertexBridge API","version":"0.1.0"},"openapi":"3.1.0","paths":{"/v1/dashboard/agreement":{"get":{"description":"The API agreement: its current text, the values we have filled in for you, and whether you have signed it.\n\n`available` is false while we are finalising the document. Nothing can be signed until it is true, and live API keys are issued only after signing — so a partner who has not signed can still build against the sandbox with test keys.","operationId":"read_agreement_v1_dashboard_agreement_get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerAgreementOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"The API agreement and your signature","tags":["dashboard"]},"post":{"description":"Sign the current version of the API agreement.\n\nYour legal name and liaison email are taken from your account rather than this request. Signing is once per version; if we publish an amendment you will be asked to sign the new one before further live keys are issued.\n\nReturns 409 if this version is already signed, and 503 while the document is still being finalised.","operationId":"sign_agreement_route_v1_dashboard_agreement_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerAgreementIn"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerAgreementOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Sign the API agreement","tags":["dashboard"]}},"/v1/dashboard/auth/forgot":{"post":{"description":"Start a password reset for a dashboard account.\n\nAlways succeeds, whether or not the address has an account. If it does, a code is emailed to it; send that code and the `challenge_token` to `POST /v1/dashboard/auth/reset`.\n\nWe email a code rather than a link, and we never send a clickable sign-in link, so a message asking you to click one did not come from us.","operationId":"forgot_password_v1_dashboard_auth_forgot_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerForgotIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerForgotOut"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Start a password reset","tags":["dashboard"]}},"/v1/dashboard/auth/login":{"post":{"description":"Sign a member in and set the dashboard session cookie.\n\nReturns 401 for any failure, with the same body in every case. Too many attempts returns 429 with the number of seconds to wait in the response body.","operationId":"login_v1_dashboard_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerLoginIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSessionOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."}},"summary":"Sign a partner member in","tags":["dashboard"]}},"/v1/dashboard/auth/logout":{"post":{"description":"Sign out of this device and clear the session cookie.\n\nSafe to call more than once.","operationId":"logout_v1_dashboard_auth_logout_post","responses":{"204":{"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."}},"summary":"Sign out of this device","tags":["dashboard"]}},"/v1/dashboard/auth/reset":{"post":{"description":"Finish a password reset with the code that was emailed.\n\nSigns every dashboard session out, including the one making this call, so sign in again afterwards with the new password. Your API keys are not affected: resetting this password changes nothing about your integration.","operationId":"reset_password_v1_dashboard_auth_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerResetIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerResetOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Finish a password reset","tags":["dashboard"]}},"/v1/dashboard/auth/session":{"get":{"description":"The member and account for the current session, or 401 if there is none.\n\nCall it when the dashboard loads to find out whether you are signed in.","operationId":"whoami_v1_dashboard_auth_session_get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSessionOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."}},"summary":"Who is signed in, for a page reload","tags":["dashboard"]}},"/v1/dashboard/auth/signup":{"post":{"description":"Create a VertexBridge account and its first member, and sign that member in.\n\nThe account starts in review. You can create test API keys and build against the sandbox immediately; live keys are enabled once we have verified your business.\n\nReturns 409 if the email address already has an account — sign in instead.","operationId":"signup_v1_dashboard_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSignupIn"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerSessionOut"}}},"description":"Successful Response"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."}},"summary":"Register a partner and its first member","tags":["dashboard"]}},"/v1/dashboard/balance":{"get":{"description":"Your prepaid balance, and the floor below which we stop accepting your traffic rather than extending credit.\n\nAmounts are strings of minor units — kobo for NGN. Parse into an integer type that does not lose precision and format for display only.\n\n`held` is the part of `balance` that is recently added money still inside its clearing window. It is included in `balance`, and it can still pay for a reversible product; what it cannot yet do is fund a payout or another irreversible one. `next_clears_at` is the earliest time any of it clears — funds arrive in tranches with their own windows, so some may remain held after that moment. `held` is zero and `next_clears_at` is null when nothing is clearing.","operationId":"balance_v1_dashboard_balance_get","parameters":[{"in":"query","name":"currency","required":false,"schema":{"default":"NGN","title":"Currency","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerBalanceOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Your prepaid balance","tags":["dashboard"]}},"/v1/dashboard/deliveries":{"get":{"description":"The webhook deliveries queued for your account, newest first, with the number of attempts and the last status code we saw.","operationId":"deliveries_v1_dashboard_deliveries_get","parameters":[{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"title":"Limit","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WebhookDeliveryOut"},"title":"Response Deliveries V1 Dashboard Deliveries Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Webhook deliveries queued for this account","tags":["dashboard"]}},"/v1/dashboard/funding":{"post":{"description":"Start a top-up of your prepaid balance and get a link to send the payer to.\n\n**Nothing is credited by this call.** Your balance moves when the payment is confirmed, which is normally seconds later. Poll `GET /v1/dashboard/balance`, or wait for the confirmation to appear in your balance history. Never treat this response as proof of payment.\n\n`checkout_url` is a VertexBridge link that redirects to the payment page. Follow it; do not parse it, and do not cache it, because it is tied to this one attempt.\n\nRecently added money is held briefly before it can fund a payout. `GET /balance` reports `held` and `next_clears_at`.","operationId":"start_funding_v1_dashboard_funding_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerFundingIn"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerFundingOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Start a top-up","tags":["dashboard"]}},"/v1/dashboard/summary":{"get":{"description":"A summary of your money movements.\n\n`volume` is what actually moved: succeeded transactions only. A failed one moved nothing, a pending one has not yet, and an indeterminate one might have.\n\n`open_indeterminate` is the money we called a provider for and cannot yet account for. It is reported beside `volume` rather than inside it, so the uncertain amount is neither counted as moved nor treated as lost.","operationId":"summary_v1_dashboard_summary_get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardSummaryOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"What moved, what is pending, and what is uncertain","tags":["dashboard"]}},"/v1/dashboard/transactions":{"get":{"description":"Every money movement on your account, newest first: purchases and payouts, what each cost you, and the state it is in now.\n\nAn `indeterminate` transaction is one we called a provider for and have not had a clear answer on. It is not a failure. We are resolving it, and this list is where the answer appears.\n\nFilter by `state` to find the ones that need attention.","operationId":"transactions_v1_dashboard_transactions_get","parameters":[{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"title":"Limit","type":"integer"}},{"in":"query","name":"state","required":false,"schema":{"anyOf":[{"maxLength":16,"type":"string"},{"type":"null"}],"title":"State"}},{"in":"query","name":"product","required":false,"schema":{"anyOf":[{"maxLength":32,"type":"string"},{"type":"null"}],"title":"Product"}},{"in":"query","name":"your_reference","required":false,"schema":{"anyOf":[{"maxLength":128,"type":"string"},{"type":"null"}],"title":"Your Reference"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DashboardTransactionOut"},"title":"Response Transactions V1 Dashboard Transactions Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Money movements on this account","tags":["dashboard"]}},"/v1/partner/agreement":{"get":{"description":"Whether this account has signed the version of the API agreement currently in force.\n\nLive API keys are issued only to an account that has signed it. If we publish an amendment, `signed` returns to false until it is signed again and no further live keys are issued until then; keys already issued keep working.\n\nSigning happens in the dashboard, by a person. This endpoint exists so your own systems can check the state without one — for example before a deploy that expects to rotate a key.\n\nThe agreement text is not returned here. Read it in the dashboard.","operationId":"agreement_status_v1_partner_agreement_get","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerAgreementStatusOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Have we signed the current API agreement?","tags":["partner"]}},"/v1/partner/balance":{"get":{"description":"Your prepaid balance, and the floor below which we stop accepting your traffic rather than extending credit.\n\nAmounts are strings of minor units — kobo for NGN — because a JSON number cannot carry them safely past 2^53. Parse into an integer type that does not lose precision, and format for display only at the edge of your own interface.\n\n`held` is the part of `balance` that is recently added money still inside its clearing window. It is included in `balance`, and it can still pay for a reversible product; what it cannot yet do is fund a payout or another irreversible one. `next_clears_at` is the earliest time any of it clears — funds arrive in tranches with their own windows, so some may remain held after that moment. `held` is zero and `next_clears_at` is null when nothing is clearing.","operationId":"balance_v1_partner_balance_get","parameters":[{"in":"query","name":"currency","required":false,"schema":{"default":"NGN","title":"Currency","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerBalanceOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"This partner's prepaid balance","tags":["partner"]}},"/v1/partner/catalogue/{product}":{"get":{"description":"The billers we can buy this product from — the networks, discos or TV providers available for `data`, `electricity` or `cable`.\n\nTake `code` from this list and send it back unchanged. It is opaque: treat it as a string, do not parse it, and do not hardcode a value you saw once. We may change what a code refers to behind the scenes, and a stored code can go stale without any visible error until it does.\n\nAn empty list means nothing is available for that product right now, not that the product does not exist.","operationId":"billers_v1_partner_catalogue__product__get","parameters":[{"in":"path","name":"product","required":true,"schema":{"title":"Product","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PartnerBillerOut"},"title":"Response Billers V1 Partner Catalogue  Product  Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Who sells this product","tags":["partner"]}},"/v1/partner/catalogue/{product}/{biller_code}":{"get":{"description":"The packages a biller offers — a data bundle, a cable TV plan.\n\n`amount_minor` is null when the biller prices it at purchase time. A prepaid electricity meter has no fixed price, and showing one would be a lie; send the amount you want instead.\n\n`requires_validation` means the customer identifier has to be checked before you can buy — a meter number belongs to a named person, and buying against a wrong one sends money somewhere unrecoverable.\n\nCodes here are opaque in the same way as a biller code.","operationId":"packages_v1_partner_catalogue__product___biller_code__get","parameters":[{"in":"path","name":"product","required":true,"schema":{"title":"Product","type":"string"}},{"in":"path","name":"biller_code","required":true,"schema":{"title":"Biller Code","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PartnerPackageOut"},"title":"Response Packages V1 Partner Catalogue  Product   Biller Code  Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"What that biller sells","tags":["partner"]}},"/v1/partner/deliveries":{"get":{"description":"The webhook deliveries queued for you, newest first, with the number of attempts and the last status code we saw.\n\nWe are not delivering webhooks yet, so every delivery here is queued and none has been attempted. Once we are, this list is where you check whether one arrived.","operationId":"deliveries_v1_partner_deliveries_get","parameters":[{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"title":"Limit","type":"integer"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WebhookDeliveryOut"},"title":"Response Deliveries V1 Partner Deliveries Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Webhook deliveries queued for this partner","tags":["partner"]}},"/v1/partner/deliveries/{delivery_id}/replay":{"post":{"description":"Queue a delivery to be sent to you again.\n\nWe are not delivering webhooks yet. This records your request; nothing leaves our side until delivery is switched on, and we will tell you before it is.\n\nDeliveries are at-least-once, so your handler must already tolerate seeing the same event twice — deduplicate on the event id header. Replaying is for a delivery your endpoint never successfully received.","operationId":"replay_v1_partner_deliveries__delivery_id__replay_post","parameters":[{"in":"path","name":"delivery_id","required":true,"schema":{"format":"uuid","title":"Delivery Id","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookReplayOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No such resource, or none belonging to this account."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Re-send a failed delivery","tags":["partner"]}},"/v1/partner/me":{"get":{"description":"Returns the partner this API key belongs to, the products it is enabled for, and the scopes the key carries.\n\nUse it to confirm an integration is wired correctly without moving money. A call that fails elsewhere for lack of a product or a scope is diagnosable from this response.","operationId":"whoami_v1_partner_me_get","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWhoamiOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Who this key belongs to, and what it may do","tags":["partner"]}},"/v1/partner/payouts":{"post":{"description":"Send `amount_minor` to a Nigerian bank account, charged to the partner.","operationId":"send_v1_partner_payouts_post","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPayoutIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPayoutOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was sent a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPayoutOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPayoutOut"}}},"description":"The rail was told and did not answer. The payout is held at `pending` and we will resolve it.\n\n**Do not retry.** The money may already be in flight. Replaying the same `Idempotency-Key` returns this same body rather than sending anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Send money to a bank account","tags":["partner"]}},"/v1/partner/payouts/banks":{"get":{"description":"The institutions a payout can reach, for building a bank picker. \n\nTake `code` from this list and send it back unchanged in `bank_code`. It is not always three characters and it is not always numeric, so do not validate or reformat it on your side.","operationId":"banks_v1_partner_payouts_banks_get","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PartnerBankOut"},"title":"Response Banks V1 Partner Payouts Banks Get","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Banks you can send a payout to","tags":["partner"]}},"/v1/partner/payouts/enquiry":{"post":{"description":"Ask who owns a bank account before sending anything to it. \n\nShow the name to whoever is sending the money and have them confirm it. We re-run this check when you send, and use the bank's spelling rather than anything you pass us.","operationId":"enquiry_v1_partner_payouts_enquiry_post","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerEnquiryIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerEnquiryOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."}},"summary":"Who owns this bank account?","tags":["partner"]}},"/v1/partner/payouts/{reference}":{"get":{"description":"The current state of a payout you sent.\n\nUse this after a 202, and after any `pending` or `indeterminate` answer. Replaying your idempotency key returns the ORIGINAL response and will never change; this returns what is true now.\n\n`indeterminate` means we still do not know whether the money moved. Do not retry and do not refund your user on it — we are asking the rail, and this endpoint is where the answer appears.","operationId":"read_v1_partner_payouts__reference__get","parameters":[{"in":"path","name":"reference","required":true,"schema":{"title":"Reference","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPayoutOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No such resource, or none belonging to this account."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"How did this payout end?","tags":["partner"]}},"/v1/partner/purchases/airtime":{"post":{"description":"Top up a phone, charged to your prepaid balance.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\n`data` carries what your customer bought, such as a meter token or a PIN reference. It is empty until the purchase succeeds, and it is the only place we return it, so store it when you receive it.\n\nA 202 means the biller was told and did not answer. Do not retry it and do not refund your customer: it may already have been delivered, and the state will resolve.\n\nSend the phone number as `customer_reference`. Airtime needs no codes.","operationId":"buy_airtime","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was bought a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"The rail was told and did not answer. The purchase is held at `pending` and we will resolve it.\n\n**Do not retry and do not refund your customer.** The biller may already have delivered. Replaying the same `Idempotency-Key` returns this same body rather than buying anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Buy airtime","tags":["partner"]}},"/v1/partner/purchases/cable":{"post":{"description":"Renew a cable TV subscription, charged to your prepaid balance.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\n`data` carries what your customer bought, such as a meter token or a PIN reference. It is empty until the purchase succeeds, and it is the only place we return it, so store it when you receive it.\n\nA 202 means the biller was told and did not answer. Do not retry it and do not refund your customer: it may already have been delivered, and the state will resolve.\n\nSend the smartcard or decoder number as `customer_reference`, and take `biller_code` and `package_code` from the catalogue and send them back unchanged.","operationId":"buy_cable","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was bought a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"The rail was told and did not answer. The purchase is held at `pending` and we will resolve it.\n\n**Do not retry and do not refund your customer.** The biller may already have delivered. Replaying the same `Idempotency-Key` returns this same body rather than buying anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Pay a cable TV subscription","tags":["partner"]}},"/v1/partner/purchases/data":{"post":{"description":"Buy a data bundle for a phone, charged to your prepaid balance.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\n`data` carries what your customer bought, such as a meter token or a PIN reference. It is empty until the purchase succeeds, and it is the only place we return it, so store it when you receive it.\n\nA 202 means the biller was told and did not answer. Do not retry it and do not refund your customer: it may already have been delivered, and the state will resolve.\n\nSend the phone number as `customer_reference`, and take `biller_code` and `package_code` from the catalogue and send them back unchanged.","operationId":"buy_data","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was bought a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"The rail was told and did not answer. The purchase is held at `pending` and we will resolve it.\n\n**Do not retry and do not refund your customer.** The biller may already have delivered. Replaying the same `Idempotency-Key` returns this same body rather than buying anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Buy a data bundle","tags":["partner"]}},"/v1/partner/purchases/electricity":{"post":{"description":"Buy electricity for a meter, charged to your prepaid balance.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\n`data` carries what your customer bought, such as a meter token or a PIN reference. It is empty until the purchase succeeds, and it is the only place we return it, so store it when you receive it.\n\nA 202 means the biller was told and did not answer. Do not retry it and do not refund your customer: it may already have been delivered, and the state will resolve.\n\nSend the meter number as `customer_reference`, and take `biller_code` and `package_code` from the catalogue and send them back unchanged. The meter token comes back in `data`.","operationId":"buy_electricity","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was bought a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"The rail was told and did not answer. The purchase is held at `pending` and we will resolve it.\n\n**Do not retry and do not refund your customer.** The biller may already have delivered. Replaying the same `Idempotency-Key` returns this same body rather than buying anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Pay an electricity bill","tags":["partner"]}},"/v1/partner/purchases/exam_pin":{"post":{"description":"Buy an examination PIN, charged to your prepaid balance.\n\nRequires an `Idempotency-Key` header. Retrying with the same key returns the original answer rather than buying a second time.\n\n`data` carries what your customer bought, such as a meter token or a PIN reference. It is empty until the purchase succeeds, and it is the only place we return it, so store it when you receive it.\n\nA 202 means the biller was told and did not answer. Do not retry it and do not refund your customer: it may already have been delivered, and the state will resolve.\n\nTake `biller_code` from the catalogue. The PIN comes back in `data` and is returned once.","operationId":"buy_exam_pin","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseIn"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"A replay. This `Idempotency-Key` was already used, and this is the original answer — nothing was bought a second time."},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"The rail was told and did not answer. The purchase is held at `pending` and we will resolve it.\n\n**Do not retry and do not refund your customer.** The biller may already have delivered. Replaying the same `Idempotency-Key` returns this same body rather than buying anything new."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"A required header is missing. Money endpoints require an `Idempotency-Key`, and it is refused before the body is validated."},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Your prepaid balance is too low for this request, including our fee. Top up and retry with a NEW idempotency key."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request conflicts with the current state. Either the same idempotency key is still in flight, or your balance has not cleared yet — `code` says which, and `retry_after_seconds` carries the wait when there is one."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too many requests. `retry_after_seconds` carries the wait; the `Retry-After` header is not relied upon."},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"We could not reach the rail, or no rail is available for this product right now. Nothing was sent."}},"summary":"Buy an exam PIN","tags":["partner"]}},"/v1/partner/purchases/{reference}":{"get":{"description":"The current state of a purchase you made.\n\nUse this after a 202, and after any `pending` or `indeterminate` answer. Replaying your `Idempotency-Key` returns the ORIGINAL response and will never change; this returns what is true now.\n\n`indeterminate` means we still do not know whether the biller delivered. Do not retry and do not refund your customer on it.\n\n`data` carries what your customer bought once the purchase has succeeded, including when it succeeded later than our first answer to you. Before that it is empty.","operationId":"read_purchase","parameters":[{"in":"path","name":"reference","required":true,"schema":{"title":"Reference","type":"string"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPurchaseOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No such resource, or none belonging to this account."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"How did this purchase end?","tags":["partner"]}},"/v1/partner/transactions":{"get":{"description":"Every money movement on your account, newest first: purchases and payouts, what each cost you, and the state it is in now.\n\nFilter by `state`, by `product`, or by `your_reference` — the reference you sent when you created the transaction.\n\n`your_reference` is the one to reach for after a request of yours timed out. If you never saw our response you will not have our `reference`, but you will still have yours, and this is how you find out whether the transaction exists.\n\nThis is a read. It never returns what a purchase delivered, so no meter token or PIN appears here.","operationId":"list_transactions","parameters":[{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"title":"Limit","type":"integer"}},{"in":"query","name":"state","required":false,"schema":{"anyOf":[{"maxLength":16,"type":"string"},{"type":"null"}],"title":"State"}},{"in":"query","name":"product","required":false,"schema":{"anyOf":[{"maxLength":32,"type":"string"},{"type":"null"}],"title":"Product"}},{"in":"query","name":"your_reference","required":false,"schema":{"anyOf":[{"maxLength":128,"type":"string"},{"type":"null"}],"title":"Your Reference"}},{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PartnerTransactionOut"},"title":"Response List Transactions","type":"array"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"Your money movements","tags":["partner"]}},"/v1/partner/webhook-signing":{"get":{"description":"How to verify the webhooks, once we send them: the algorithm, the exact material that is signed, the header names, and the replay window in seconds.\n\nServed from the same constants the sender will use, so this response cannot drift from what we will sign. Build against it now; we are not delivering webhooks yet and will tell you before we start.","operationId":"signing_docs_v1_partner_webhook_signing_get","parameters":[{"in":"header","name":"X-API-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSigningOut"}}},"description":"Successful Response"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"No credential, or one that is not valid."},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Authenticated, but not permitted — a missing scope, a product that is not enabled for this account, or an account that is not active."},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"The request body or query string did not validate."}},"summary":"How to verify the webhooks we send","tags":["partner"]}}}}