---
title: PartnerApi
description: Session sign-in, API key management, attributed orders, referral claiming, and gas sponsorship funding.
---
import {
LOGIN_CODE_TTL_MINUTES,
LOGIN_CODE_MAX_ATTEMPTS,
SESSION_DAYS_DEFAULT,
SESSION_DAYS_KEEP,
SESSION_REVOKE_MIN_AGE_HOURS,
STATS_MAX_RANGE_DAYS,
STATS_MIN_STEP_SECS,
STATS_MAX_POINTS,
DEFAULT_PAGE_LIMIT,
MAX_PAGE_LIMIT,
} from "/snippets/vars.mdx";
Everything here is scoped to one partner and requires a session token in an `authorization: Bearer` header, except the two sign-in methods.
## Sessions
### RequestLoginCode
```
rpc RequestLoginCode(RequestLoginCodeRequest) returns (RequestLoginCodeResponse)
```
Emails a six-digit code to `email`. Empty response. Repeat requests inside a minute are rejected rather than sending a second email.
Address to send the code to.
Cloudflare Turnstile token from the sign-in widget. Single-use; verified server-side before any code is sent.
### VerifyLoginCode
```
rpc VerifyLoginCode(VerifyLoginCodeRequest) returns (PartnerSession)
```
Address the code was sent to.
The six-digit code. Valid for {LOGIN_CODE_TTL_MINUTES} minutes and {LOGIN_CODE_MAX_ATTEMPTS} attempts, after which it is discarded.
Extends the session from {SESSION_DAYS_DEFAULT} day to {SESSION_DAYS_KEEP} days.
Session token. Send as `authorization: Bearer `.
Expiry timestamp.
### Logout
```
rpc Logout(LogoutRequest) returns (LogoutResponse)
```
Invalidates the calling session immediately.
### ListPartnerSessions
```
rpc ListPartnerSessions(ListPartnerSessionsRequest) returns (PartnerSessionsPage)
```
Every live session on the account, most recently active first.
Each with `id`, `ips`, `user_agent`, `created_at`, `expires_at`, `last_used_at`, and `current`. `ips` lists every address the session has been used from, each with `ip`, a best-effort `location`, and `last_seen`. `current` marks the session making the call.
Whether the calling session is old enough to revoke others; see `RevokePartnerSession`.
### RevokePartnerSession
```
rpc RevokePartnerSession(RevokePartnerSessionRequest) returns (RevokePartnerSessionResponse)
```
Takes a session `id` and invalidates it immediately. The calling session must be at least {SESSION_REVOKE_MIN_AGE_HOURS} hours old, so a freshly stolen token cannot immediately evict the account's other sessions; a younger session gets `PERMISSION_DENIED`. The calling session cannot revoke itself; use `Logout` for that.
## Usage
### GetPartnerApiStats
```
rpc GetPartnerApiStats(PartnerApiStatsRequest) returns (PartnerApiStats)
```
Time-bucketed request and rate limit metrics for your API keys, powering the panel's Usage tab.
Window ending now. Defaults to one day; at most {STATS_MAX_RANGE_DAYS} days.
Bucket width. Defaults to five minutes; at least {STATS_MIN_STEP_SECS} seconds, and the range may span at most {STATS_MAX_POINTS} buckets.
One series per `(key_id, method, status)` with request counts per bucket. `status` is the lowercase gRPC code name: `ok`, `resource_exhausted`, `invalid_argument`, and so on.
One series per `key_id` with rate limit points consumed per bucket.
## API keys
### GetPartner
```
rpc GetPartner(GetPartnerRequest) returns (Partner)
```
Partner email.
Existing keys, each with `id`, `key`, `name`, `tier`, `points_per_min`, `disabled`, and `created_at`. `points_per_min` is the key's rate limit budget; unset means the deployment default.
Cap on active keys.
### CreatePartnerApiKey
```
rpc CreatePartnerApiKey(CreatePartnerApiKeyRequest) returns (PartnerApiKey)
```
Takes a `name` and returns the created key, including its secret value. Name keys after the surface that uses them: the name comes back on attributed orders.
### RevokePartnerApiKey
```
rpc RevokePartnerApiKey(RevokePartnerApiKeyRequest) returns (RevokePartnerApiKeyResponse)
```
Takes an `id`. Requests using that key then fail with `api key disabled`, within a few seconds of the change.
## Attributed orders
### ListPartnerOrders
```
rpc ListPartnerOrders(ListPartnerOrdersRequest) returns (PartnerOrdersPage)
```
Orders originated by your keys, newest first.
Page size. Defaults to {DEFAULT_PAGE_LIMIT}, clamped to {MAX_PAGE_LIMIT}.
Cursor from the previous page.
Each carries `quote_hash`, `state`, `src_chain`, `dst_chain`, `deposit_token`, `deposit_amount`, `deposit_symbol`, `deposit_decimals`, `referrer_fee`, `api_key_name`, and `created_at`.
Absent on the last page.
## Referrals
### GetPartnerReferrals
```
rpc GetPartnerReferrals(PartnerReferralsRequest) returns (PartnerReferralsPage)
```
Claimable balances, grouped.
Each carries `referrer`, `chain`, `chain_id`, `token`, `token_symbol`, `decimals`, `amount`, and the `count` of orders behind it.
Absent on the last page.
### ClaimPartnerReferrer
```
rpc ClaimPartnerReferrer(ClaimPartnerReferrerRequest) returns (Voucher)
```
Referrer address to claim for.
Chain the balance accrued on.
Token the balance is denominated in.
Marks the covered orders claimed, totals them, and returns a signed [Voucher](/api-reference/types#voucher). The voucher can only pay the referrer address embedded in it.
### ListPartnerVouchers
```
rpc ListPartnerVouchers(PartnerVouchersRequest) returns (ListVouchersResponse)
```
Every voucher issued to you with its redemption status, kept current from on-chain `VoucherRedeemed` events. Takes no arguments.
### BuildVoucherRedemption
```
rpc BuildVoucherRedemption(BuildVoucherRedemptionRequest) returns (VoucherRedemptionTx)
```
Voucher to redeem.
Address that will pay the transaction fee. It does not have to be the referrer.
Prepared transaction, base64 encoded. On Solana it already includes the ed25519 verification instruction the program requires.
EVM vouchers can instead be redeemed by calling `redeemVoucher` directly with the fields from the voucher; the `calldata` field on the voucher carries a ready-to-send payload.
## Funding
A funding balance pays the relay gas for quotes requested with `sponsor_fees`, so the cost comes out of the partner's prepaid balance instead of the user's output. Deposits are made on one designated chain through the router's `fundPartner` entry point; debits happen per sponsored order. See [SubmitGaslessOrder](/api-reference/gasless).
### GetPartnerFunding
```
rpc GetPartnerFunding(GetPartnerFundingRequest) returns (PartnerFunding)
```
Takes no arguments.
Total balance across funding tokens, USD micros.
The funding chain. Deposits and balances live here.
Its EVM chain id. Optional.
Router contract that `fundPartner` is called on.
Tokens accepted for funding, each with `chain`, `chain_id`, `address`, `symbol`, and `decimals`.
Current balance per token: `token`, `amount` in base units, and `usd_micros`.
### BuildPartnerFunding
```
rpc BuildPartnerFunding(BuildPartnerFundingRequest) returns (PartnerFundingTx)
```
One of the accepted funding tokens.
Amount to deposit, base units.
Registers a funding id and returns the transaction to send: `router_address`, ready `calldata` for `fundPartner`, and `value` (non-zero for a native deposit). The deposit is credited once the indexer sees the `PartnerFunding` event carrying that id.
### ListPartnerFundingActivity
```
rpc ListPartnerFundingActivity(PartnerFundingActivityRequest) returns (PartnerFundingActivityPage)
```
Takes an optional `limit`, defaulting to {DEFAULT_PAGE_LIMIT} and clamped to {MAX_PAGE_LIMIT}. Returns `entries` newest first, each with a `kind` of `deposit` or `debit`, the `delta`, `token`, `created_at`, and a `status` of `pending` or `credited`. Deposits carry their `funding_id` and `tx_hash`; debits carry the `quote_hash` of the sponsored order.
## Errors
| Code | Message | When |
| --- | --- | --- |
| `UNAUTHENTICATED` | `missing session token` | No bearer header. |
| `UNAUTHENTICATED` | `invalid or expired session` | Session is unknown or past expiry. |
| `INVALID_ARGUMENT` | `invalid code` | Wrong code. |
| `INVALID_ARGUMENT` | `code expired; request a new one` | Past its lifetime or out of attempts. |
| `INVALID_ARGUMENT` | `token not allowed for funding` | `BuildPartnerFunding` with a token outside the accepted list. |
| `FAILED_PRECONDITION` | `funding is not configured` | The deployment has no funding chain configured. |