Reference
Every route Wire exposes.
Flow (prompt-to-payment pages), Relay (any API → MCP tools), and the account/payout endpoints underneath both. Generated directly from the route handlers in app/api/ — every request/response shape below reflects what the code actually does, not an aspirational spec.
https://usewiree.vercel.app/
Session auth
An httpOnly cookie (wire_session) set by /api/auth/login or /api/auth/signup. Required for anything scoped to an account.
Public
No auth — either genuinely public reference data, or intentionally open (Flow creation itself needs no account).
Signed webhook
Verified via an HMAC signature header from the sender (Paystack, Twilio) — not something you call directly.
Cron secret
Guarded by an Authorization: Bearer $CRON_SECRET header Vercel sends automatically on schedule.
Flow
The prompt-to-payment-page pipeline. Call it with no auth at all for an anonymous, unowned page, or with your developer API key (see Auth below) to create pages under your own account — e.g. from your own backend, not through Wire's UI.
Turns one plain-English request into a live Flow page — single price, multiple named tiers, or a recurring subscription, decided automatically from the wording. Pass "Authorization: Bearer <your dev key>" to create it under your own account instead of anonymously; omit it and the page is unowned until someone logged-in claims it by viewing its dashboard.
Body
| Field | Type | Description | |
|---|---|---|---|
| prompt | string | required | What's being sold, in plain English — price (or per-tier prices, or a recurring frequency) included. |
| sellerId | string | optional | The wire_seller_id browser cookie value, so the page can be claimed later by whoever logs in from this browser. Not needed when authenticating with a dev key — ownership is already resolved from that. |
Response
{
"slug": "a1b2c3d4",
"checkoutUrl": "/checkout/a1b2c3d4",
"dashboardUrl": "/dashboard/a1b2c3d4",
"record": { "apiKey": "flow_...", "...": "see FlowRecord" }
}Status
Every Flow page the logged-in user owns. Also sweeps in and claims any unowned page created from this same browser first.
Response
{
"email": "you@example.com",
"flows": [ /* FlowRecord[] */ ]
}Status
Polled every 3s by the dashboard. With a browser session, claims an unowned page for the current viewer on first load and 403s if it's already owned by someone else. With "Authorization: Bearer <the Flow's own apiKey>" (returned when it was created, not your developer key) it skips ownership entirely — this is the status-check path for a third-party app.
Response
// FlowRecord, plus subscriberCount if the Flow is recurring
{ "...": "see FlowRecord", "subscriberCount": 4 }Status
Tiered Flows only. Creates a one-off invoice for the chosen tier's price — there's no single fixed checkout link when a page has tiers.
Body
| Field | Type | Description | |
|---|---|---|---|
| tierId | string | required | One of the tier ids from the Flow's tiers array. |
Response
{ "checkoutUrl": "https://checkout.paystack.com/..." }Status
A standalone PNG QR code pointing at the Flow's checkout page — used to hand WhatsApp a public image URL, but works for anything that needs the raw image.
Response
// image/png bytes, not JSON
Status
Payouts
Lets a seller route their share of every sale straight to their own bank account via a Paystack subaccount, instead of it pooling in the platform wallet.
The full bank list for the payout-setup dropdown.
Response
{ "banks": [ { "name": "GTBank", "code": "058" }, ... ] }Status
The logged-in user's payout account, if they've set one up.
Response
{ "account": /* PayoutAccount */ null }Status
Creates a Paystack subaccount for this user (once) and saves it. Defaults to a 100% split — the seller keeps everything unless a platform fee is set explicitly.
Body
| Field | Type | Description | |
|---|---|---|---|
| bankCode | string | required | From the /api/banks list. |
| accountNumber | string | required | The seller's own bank account number. |
| bankName | string | optional | Display label only — passed through from the client's bank list lookup. |
| splitPercentage | number | optional | Defaults to 100. |
Response
{ "account": /* PayoutAccount */ }Status
Relay & MCP
Turns a pasted curl command or OpenAPI spec into real MCP tools, plus the fixed Paystack-preset gateway every Flow page is built on.
Parses a curl command or OpenAPI JSON spec into a gateway and registers it, ready to be pointed at by /api/gateway/{id}/mcp.
Body
| Field | Type | Description | |
|---|---|---|---|
| input | string | required | A curl command, or an OpenAPI spec as JSON text. |
| authValue | string | optional | Bearer token / API key / basic-auth credentials for the target API. |
| persist | boolean | optional | true keeps the gateway indefinitely (e.g. for /connect); otherwise it expires after 30 days. |
Response
{
"id": "gw_x1y2",
"sourceLabel": "curl: api.example.com",
"baseUrl": "https://api.example.com",
"auth": { "type": "bearer" },
"operations": [ /* GatewayOperation[] */ ]
}Status
The live MCP server for a generated gateway — point any MCP-capable client at this URL. Stateless: re-compiled from the stored spec on every request.
Response
// Streamable HTTP MCP transport, not a plain JSON body
Status
A downloadable MCP client config file (mcpServers block) pointing at the gateway above.
Response
{ "mcpServers": { "wire-gateway-gw_x1y2": { "url": "...", "description": "..." } } }Status
The fixed Paystack-preset MCP server — six tools (invoice, reserved account, sub-account split, refund, wallet balance, transaction search).
Response
// Streamable HTTP MCP transport
Status
Downloadable MCP client config for the Paystack preset above.
Response
{ "mcpServers": { "wire-paystack": { "url": "...", "description": "..." } } }Status
The Playground's live test chat — streams Server-Sent Events as the agent reasons, calls tools, and gets results back, against either the Paystack preset or a generated gateway.
Body
| Field | Type | Description | |
|---|---|---|---|
| message | string | required | What to ask the agent to do. |
| gatewayId | string | optional | Use a generated gateway's tools instead of the Paystack preset. |
Response
// text/event-stream — events: reasoning, tool_call, tool_result, error, done
event: tool_call
data: {"tool":"get_wallet_balance","input":{}}
event: tool_result
data: {"tool":"get_wallet_balance","output":{...},"isError":false}Status
Auth
The whole account system — email + password, hashed with scrypt, sessions stored in Redis behind a random-token cookie.
Creates an account and starts a session.
Body
| Field | Type | Description | |
|---|---|---|---|
| string | required | Must contain “@”. | |
| password | string | required | At least 8 characters. |
Response
{ "email": "you@example.com" }Status
Verifies credentials and starts a session.
Body
| Field | Type | Description | |
|---|---|---|---|
| string | required | ||
| password | string | required |
Response
{ "email": "you@example.com" }Status
Ends the current session and clears the cookie.
Response
{ "loggedOut": true }Status
Who's currently logged in.
Response
{ "email": "you@example.com" }Status
Your developer API key — creates one on first request, returns the same one on every call after that. This is what you put in your own backend's config; pass it as "Authorization: Bearer <key>" on POST /api/flow to create Flow pages under your account without a browser session. Distinct from a single Flow's own apiKey (returned when that Flow is created), which only ever authenticates GET requests for that one Flow's status.
Response
{ "apiKey": "dev_..." }Status
Connect
Ties a seller's browser identity to a system they've connected (Airtable, Notion, etc.), so a confirmed sale can trigger an action there.
Saves the link between a sellerId (browser cookie) and a gateway they've connected.
Body
| Field | Type | Description | |
|---|---|---|---|
| sellerId | string | required | |
| gatewayId | string | required | |
| sourceLabel | string | optional | Defaults to “Connected system.” |
Response
// SellerRecord
{ "sellerId": "...", "gatewayId": "...", "sourceLabel": "...", "connectedAt": "..." }Status
Looks up what a given sellerId has connected, if anything.
Response
// SellerRecord
Status
Internal & inbound webhooks
Not meant to be called directly — documented for completeness. Each is only reachable by the specific external sender its signature/secret is checked against.
Paystack's charge.success notifications. Verifies x-paystack-signature (HMAC-SHA512 over the raw body, keyed with the secret key), records the sale, captures a reusable authorization for recurring billing, and fans out to any connected system.
Response
{ "received": true }Status
Inbound WhatsApp messages via Twilio. Verifies X-Twilio-Signature, then runs the same Flow-creation agent a browser request would, replying over WhatsApp.
Response
// 200 with an empty body in every case Twilio should not retry
Status
Fired daily by Vercel Cron (see vercel.json). Charges every recurring subscription whose next cycle is due, via Paystack's charge-authorization API.
Response
{ "charged": 3, "results": [ { "id": "...", "ok": true }, ... ] }Status
Data types
The shapes referenced above, as they’re actually stored — every optional field is genuinely optional depending on which kind of Flow it is.
FlowRecord
slug, title, priceNaira, ticketCap, ticketsSold, revenueNaira,
accountReference, accountNumber?, bankName?, checkoutUrl?,
createdAt, tiers?: FlowTier[], recurring?: { frequency },
userId?, sellerId?, lastConnectedAction?accountNumber/bankName/checkoutUrl are only set for single-price Flows — tiered and recurring pages don't have one fixed payment target.
FlowTier
id, name, priceNaira, cap, sold
One entry per named tier on a multi-tier Flow.
PayoutAccount
subAccountCode, bankCode, bankName, accountNumber, accountName?, splitPercentage, createdAt
One per user — created via POST /api/payout, referenced (not recreated) on every future sale.
SellerRecord
sellerId, gatewayId, sourceLabel, connectedAt
Links a browser/WhatsApp identity to a connected external system.
GatewayOperation
name, description, method, path, params: GatewayParam[]
One entry per endpoint a pasted API exposed. GatewayParam: name, location (path/query/header/body), type, required, description.