Organisation
Markup, credentials, people, and the numbers on your dashboard.
Everything on this page is administration of your own organisation. All of it
needs an organisation admin signed in as a user, since
API keys do not qualify.
The exceptions are GET /config and GET /stats, which any credential can
read.
Configuration
GET /config returns four fields.
| Field | Meaning |
|---|---|
markup_pct | your resale markup, applied on top of the platform's price |
markup_locked | whether you may change it |
rate_limit_rpm | your requests-per-minute allowance |
is_internal | whether this is a platform-internal organisation |
PUT /config changes the markup and nothing else. If markup_locked is true,
meaning your pricing has been fixed for you, it returns 403 with markup is locked by admin. Reading markup_locked before offering the control is the
friendlier way to handle that.
The markup feeds straight into catalog pricing. It is one of the two components
sitting on top of a wallet's base price, alongside the platform's own margin for
that wallet's tier. Change it and every user_price in the catalog moves with
it.
Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Response Body
application/json
curl -X GET "https://example.com/config"{ "is_internal": true, "markup_locked": true, "markup_pct": "string", "rate_limit_rpm": 0}Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X PUT "https://example.com/config" \ -H "Content-Type: application/json" \ -d '{ "markup_pct": "string" }'{ "is_internal": true, "markup_locked": true, "markup_pct": "string", "rate_limit_rpm": 0}API keys
Covered under Authentication: creating one, the fact that the secret is shown exactly once, and revoking it.
People
Users belong to one organisation and hold one of two roles, org_admin or
org_member. Admin is what unlocks this page.
There is no sign-up form. You invite an address, they get an email, they
register with the token in it. POST /users/invite defaults to org_member
when no role is given.
PUT /users/{id}/status flips a user between active and disabled. A
disabled user's tokens stop working on the next request, because the check is on
the account rather than on the token, so there is no window to wait out.
Pending invitations live at GET /invitations until they are accepted, and
DELETE /invitations/{id} withdraws one that should not have gone out.
Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Response Body
application/json
curl -X GET "https://example.com/users"[ { "created_at": "string", "email": "string", "id": "string", "last_login_at": "string", "name": "string", "org_id": "string", "role": "string", "status": "string" }]Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X POST "https://example.com/users/invite" \ -H "Content-Type: application/json" \ -d '{ "email": "string" }'{ "accepted_at": "string", "created_at": "string", "email": "string", "expires_at": "string", "id": "string", "org_id": "string", "role": "string", "status": "string"}Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Path Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
curl -X PUT "https://example.com/users/string/status" \ -H "Content-Type: application/json" \ -d '{ "status": "string" }'{ "ok": true}Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Response Body
application/json
curl -X GET "https://example.com/invitations"[ { "accepted_at": "string", "created_at": "string", "email": "string", "expires_at": "string", "id": "string", "org_id": "string", "role": "string", "status": "string" }]Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Path Parameters
Response Body
application/json
curl -X DELETE "https://example.com/invitations/string"{ "ok": true}Dashboard numbers
GET /stats is the summary: how many orders you have placed, how many wallets
you hold, how many quotes are open right now, and your spend, margin and balance
broken down per chain.
The per-chain breakdown is not an accident. Base units mean different things on
different chains, so a single cross-chain total would be meaningless. Price each
chain's native token with GET /prices and sum in USD if you want one number.
Authorization
bearerAuth JWT from /auth/login (users) or an org API key (mk_...) for integrations.
In: header
Response Body
application/json
curl -X GET "https://example.com/stats"{ "active_quotes": 0, "balances": [ { "amount": "string", "chain": "string" } ], "margin_by_chain": [ { "amount": "string", "chain": "string" } ], "spent_by_chain": [ { "amount": "string", "chain": "string" } ], "total_purchases": 0, "wallets_bought": 0}Last updated on