This article covers the tokens that let a script, a CI job or an AI agent act on your account — your listings, Worker code, pricing and analytics, and your own subscriptions and API keys — without your login.The Management API is the same REST the API Studio and the Workspace use. A management token stands in for your session on those routes, and nothing else changes: the same validation, the same ownership checks, the same audit trail. What the token may do is set by its scopes, and optionally limited to some of your APIs or projects.
Management tokens are not API keys
Give each script or agent its own token with only the scopes it needs, set an expiry, and revoke it when the job is done.
Create a token
Open Settings › Tokens (Settings is in the user menu, top right) and choose Create token:- Name it after what will use it.
- Pick the scopes, or start from a template and adjust it.
- Limit it to some of your APIs or projects if the job touches only those (optional).
- Set a spend limit if it has
subscriptions:write. - Set an expiry, up to a year.
Templates
Scopes
Scopes areresource:action. A route needs all the scopes listed for it; a few writes need one more scope depending on what they change, noted below.
Your APIs
Your Workspace and account
Settings › Tokens marks
keys:read, request-logs:read and payment-methods:charge as sensitive: a leaked token with one of them leaks your API keys or your consumers’ data, or can charge your cards up to its spend limit.
Never on a token
Some actions stay with a person signed in to the Studio, whatever scopes a token holds:- Money in and out of your account: top-ups, auto top-up, adding, removing or ordering payment methods and the billing profile; card, PayPal and crypto checkouts.
- Your account itself: profile, username and photo; sign-in, password, email, social connections and two-factor authentication.
- Tokens and people: creating, changing or revoking management tokens; organization members.
- Owner actions: deleting an API, payout methods, verification and accepting the provider terms.
Limit a token to some APIs or projects
A token can be limited to some of your APIs, some of your projects, or both:- APIs limit the routes that act on one of your APIs (listing, pricing, code, observability, customers). Every other API is refused with
resource_not_allowed. - Projects limit the routes that act on projects and their API keys, and usage by key. Keys of other projects are refused.
- Lists narrow.
ProviderApis,projectsandapi-keyslist only what the token may use. - Routes that cover everything are refused to a limited token: for an API limit, the Studio dashboard, traffic and uptime totals, transactions, payouts, subscribers and creating an API; for a project limit, the Workspace dashboard and creating a project. Routes with an optional filter (
apifor Studio analytics and request logs,projectorapi_keyfor usage) work when the request names one the token may use.
Paying with a token
A token withsubscriptions:write can subscribe to plans, pay a past-due subscription and accept a plan transfer. It pays like this:
- From the wallet first, in USD. Top up the wallet in the Workspace before an agent needs it.
- Saved payment methods only with
payment-methods:charge. When the wallet does not cover a payment, a token with this scope charges your saved payment methods in their order, without you, the way a renewal is charged; a card that asks for 3-D Secure fails. Without the scope the token pays from the wallet only. - Within its spend limit per calendar month, counted from everything the token paid — wallet and cards — net of refunds. The limit is a setting of the token, required with
subscriptions:write;0allows free and pay-as-you-go plans only. - You hear about it. Every subscription a token makes emails you with the token’s name and its spend this month.
API keys and agents
Tokens withkeys:read can read your API keys, but the answers keep the values out of sight unless a request asks for them:
- Masked by default.
GET v1/api-keysreturns each key’spreviewasjk_••••••••abcdwithmasked: true, andcreate-api-keyreturns the new key the same way. - Revealed on request.
reveal=true(in the query string of a GET, in the JSON body of a POST) returns the values. Only a token withkeys:readgets them;keys:writealone never does. - Keys by id. Every key carries an
id(n…).delete-api-key,set-api-key-label,set-api-key-restrictionsandset-api-key-gateway-headerstake that id in place of the key, so managing keys never needs their values.
jojapi keys create --to-env-file .env — so your code can read it from there. Ask for reveal=true only when a person needs to see the key, and never paste a key into a prompt, a log or an issue.
Check a token
GET v2/management-token describes the token that calls it — every token can call it:
wallet is there for tokens with subscriptions:write or billing:read. jojapi whoami prints the same.
Calling it
Thejojapi CLI wraps these routes in commands with previews and confirmations. To call the routes directly, send the token as a bearer token to the REST routes under https://app.jojapi.com/rest/. If a proxy in front of your script strips Authorization, the header X-Management-Token: jm_… is accepted too.
Answers are JSON with a status field; the HTTP status is 200 for every answer the application produced, so read status, not the code:
Tokens created before these scopes
Tokens created before these scopes hold the earlier ones and keep exactly the access they had, so CLI logins, CI secrets andjojapicom/deploy-action need no change. Settings › Tokens marks them Legacy scopes and offers Upgrade scopes: it proposes the current scopes that cover everything the token can do today, you remove what it does not need, and the token keeps its value.
New tokens get the current scopes only.
Routes
Every route takes and returns JSON.GET routes take their parameters in the query string; POST routes take a JSON body. slug is an API’s slug — the last part of its Studio URL.
Listings
update-endpoint-details replaces the endpoint’s details and billing together. Sending the stored billing back unchanged, as the CLI does when it renames an endpoint, needs endpoints:write only.
Imports — publishing an OpenAPI document
The fastest way to keep a listing in step with your code is to publish its OpenAPI document. An import never touches an existing endpoint’s blocked/hidden flags, its group or its plans unless you ask it to.bundle is a JSON string in the import engine’s source-agnostic shape:
value_type is one of string, enum, number, integer, boolean, date, time, object, array, geopoint. Preview first, read the diff, then apply.
Pricing
create-api-plan answers the new plan as plan: {slug, type, blocked}. A public plan must fit the pricing page: at most 10 public plans per API, one of them pay-as-you-go. This applies both when you create a plan as public and when update-api-plan makes a private plan public; over the limit the status is public_plans_limit_reached. Public plans with the same name share a card on the pricing page, so two of them can’t have the same period and rate limit: create-api-plan, update-api-plan and update-plan-display answer plan_card_conflict to a change that would make such a pair (see How plans appear on the pricing page).
Analytics, customers and earnings
Subscriptions and plan transfers are identified by opaque string ids (
subscription.id, pending_transfer.id). Send them back exactly as you received them; they are not row numbers. studio/grant-quota takes the subscription.id that ProviderSubscriptions returns and an object_id from that subscription’s current_period.objects.
Worker code (edge gateway)
Every save is a preview unless it sends
production: true, which also needs deployments:promote; note is the public release note of a production save. A save returns deploy: deployed with the new deployment (id, number, url) and whether it was promoted, or error with the build message. deploy.pending (also in provider-api-edge and provider-api-edge-deployments) lists what production does not run yet: changes ([{type: mode | template | file | variable | resource, name, change: added | changed | removed}]), production ({id, number}) and deployment, the latest preview ({id, number, status, error, url, current}; current: false means no deployment holds the saved changes yet). preview: true is still accepted and changes nothing. See Deployments and Worker code.
Your subscriptions
Projects and API keys
Usage, billing, messages and activity
The public catalog
POST v1/marketplace/search, GET v2/api-page, GET v2/UserPage, GET v2/landing-page, GET v2/sitemap-data and GET v2/billing-countries need no scope; any token with the current scopes can call them. api-page of one of your own APIs needs apis:read, since it shows hidden endpoints too.
