Approve the Revolut counterparty before the first payment
A Revolut counterparty in state created is not a paid transfer. Payment drafts wait for approval in the Business app, and request_id dedupes for two weeks.
Key takeaways
- -In this article we explore the Revolut Business API and the approval step before a first payment.
- -A counterparty state of created means Revolut stored the recipient. It does not mean a payment was approved.
- -Payment drafts stay drafts until someone sends them in the Revolut Business app. Pending review needs an approver in that app.
- -request_id on POST /pay prevents a duplicate transfer for about two weeks. A new id is a new transfer.
The agent creates a supplier and immediately calls pay. Revolut returns the counterparty id. The transfer comes back declined or failed. The id was real. Nobody in the Business app had approved a payment to that supplier, and the token used a path that still needed a human.
This post maps the Revolut Business sequence that has to finish before the first real transfer: counterparty, draft, approval, then the request_id you must reuse if the call times out.
Create the counterparty, then read its state
Add a counterparty returns an id and a state. The documented values are created, draft, and deleted. There is no approved value on that object. A created counterparty means Revolut stored the recipient. It does not mean a payment has cleared.
Names are strict. A Revtag counterparty uses name. A company added by bank details uses company_name. An individual added by bank details uses individual_name. Mix those fields and the create fails. A Revtag name that does not match the account returns a 404. Fill street_line1, region, and city along with the required country and postcode. Revolut says some rails reject a thin address later, at payment time, which is a bad moment to discover it.
If the recipient has more than one account or a card, a later transfer has to name receiver.account_id or receiver.card_id. An agent that only stores the counterparty id will be under-specified on the second hop.
The Revolut catalog page is where the downloaded methods live. swy search revolut finds the provider. Copy ids from swy list methods. Do not guess a method name for "pay supplier."
Approval lives on the draft, in the Business app
Create a payment draft keeps the payment as a draft until someone sends it for processing in the Revolut Business app. If your business uses an approval rule, that send moves the payment to Pending review. An owner, an admin, or another designated approver has to approve it in the app before processing.
That is the control. A draft the API created is still reversible: you can delete it while it is a draft. A transfer that already ran is a different story.
POST /pay is the direct transfer. The create-transfer reference says a payment to another Revolut account is instant. States you can get back include created, pending, completed, declined, failed, and reverted. declined and failed cover insufficient balance, bad receiver data, blocked payments, and invalid calls. reverted can mean the receiver was unreachable.
Scopes decide which of these the token may call. Revolut documents READ for GET calls, WRITE for counterparties, webhooks, and payment drafts, and PAY for initiating or cancelling transactions and exchanges. A token with PAY can skip the draft queue. A token with WRITE and not PAY can prepare a draft and cannot fire the transfer. Give the agent the WRITE token until the approval habit is real. Add PAY in a later change, for the methods you mean to run.
Treasury agents and bank APIs is the wider pattern. This Revolut path is the specific gate: the draft, then a person in the Business app. Human approval on Slack or Telegram is a separate hold, on Business and Enterprise plans. It does not replace the Revolut approver. You may want both. The Revolut one is the one that releases the money.
A request id lasts about two weeks
POST /pay takes a request_id you choose. Revolut recommends a UUID v4. If the HTTP call times out, send the same request_id again. If a transaction with that id already exists, Revolut does not create another.
The window is short on purpose. Idempotency applies to transactions created in the last two weeks. Reuse the same request_id after that and Revolut may create a new transaction. Store the id next to the attempt. An agent that mints a new UUID after every timeout will pay twice, inside the window, because Revolut has never seen that new id.
There is no .env file in this project. Swytchcode keeps credentials in its own local store and reads them when a call runs. The PAY token stays in that store.
Sandbox counterparties are test Revtags
Sandbox will not add a real person or business as a Revolut counterparty via Revtag. Revolut publishes test pairs. Test User 1 with revtag john1pvki through Test User 9 with john9pvki. Use those pairs for name and revtag. A live supplier Revtag in sandbox fails for a reason that has nothing to do with your payment logic.
Run the sandbox path with a test Revtag, a draft, and a request_id you can show twice. Turn on PAY only after a declined or failed response is something you have already logged and understood.
Related reading
- API compliance for agent integrations. How to describe the draft-then-approve sequence in a review.
- Policy as code for agent calls. Where a
PAYmethod stays denied until you allow it. - Log every API call an agent makes. Where the
request_idand the transaction state should show up. - A security checklist before company data. What to settle before a supplier bank account is in the agent.
FAQ
If the counterparty state is created, can I pay them?
You can call POST /pay if the token has the PAY scope and the receiver fields are complete. created does not mean an approver has seen the payment. Use a payment draft when a person in the Revolut Business app must release it.
How long can I retry the same Revolut request_id?
About two weeks from the transaction. The same id inside that window does not create a second transfer. After that, Revolut says reuse can create a new transaction. Keep the original id with the attempt.
Why did Revtag lookup return 404?
The name must match, or closely match, the account. In sandbox, use Revolut's published test users, such as Test User 1 and john1pvki. A live person's Revtag is not a sandbox counterparty.
Does a Swytchcode approval replace Revolut's approver?
No. Slack or Telegram approval is available on Business and Enterprise and expires after 48 hours. Revolut still applies its own draft and Pending review rules inside the Business app. Keep the Revolut step even if you also hold the call in Swytchcode.
More content
Circle API transfers and the idempotency key you must reuse
Circle puts idempotencyKey, a UUID v4, in the transfer body. Reuse that key on a retry. A new key starts a second transfer. Code 1083 means the body changed.
How to query the GDELT API without drowning the agent
GDELT's DOC API needs no key. The default search is three months of HTML, up to 75 articles. Set timespan, maxrecords, and format=json, then wait out a 429.
Bitbucket API tokens and the username that causes a 401
Bitbucket app passwords stopped being the supported path in 2026. API tokens use your Atlassian email, need scopes, and can be limited to one workspace.
