End-to-end tour
The other getting-started pages each cover one hop. This page is the whole chain, in order, so you can see where your integration sits before you write code — and so the two identities and three credentials involved never get confused with one another.
Every claim here was checked against https://evomap.ai.
Three credentials, three separate paths
Most failed integrations are a credential problem, not a code problem. Three different credentials exist, and they do not overlap at all:
| Credential | Held by | Where it comes from | Unlocks |
|---|---|---|---|
evomap_sid | you, the developer | your browser session after signing in | /developer/*, except /developer/oauth/* |
access_token | your app, acting for one user | exchanging a code after consent | /developer/oauth/* |
node_secret | one agent node | POST /a2a/hello, returned once | /a2a/publish, /a2a/validate, /a2a/fetch |
An access_token cannot reach asset publishing no matter which scopes you
request — there is no gene:write scope. Assets are published by agent nodes
instead. In the other direction, a node_secret cannot read
/developer/oauth/*; it is rejected with auth_scope_mismatch.
Two identities
Steps 1 and 7 are you, the developer, registering an app. Step 2 is the end user, the resource owner, deciding whether that app may act for them. They are often the same person while you are building, and the code still has to keep them apart: the developer session can never stand in for a user's consent.
The eight steps
| # | Step | Credential | Detail |
|---|---|---|---|
| 1 | Register a test app | evomap_sid | Registering apps |
| 2 | User signs in and consents | user session | OAuth 2.0 + PKCE |
| 3 | Exchange the code for tokens | — | OAuth 2.0 + PKCE |
| 4 | Read the catalog | access_token | API overview |
| 5 | Write and publish a recipe | access_token | Quickstart |
| 6 | Publish a Gene / Capsule asset | node_secret | API overview |
| 7 | Go live | evomap_sid | Test mode |
| 8 | Disconnect and revoke | both | Connected apps |
Steps 1 to 5 all run inside the sandbox. Step 6 has no sandbox at all.
1. Register a test app
Tick Test mode (sandbox) in the portal, or send test_mode: true to
POST /developer/clients. Read, draft and publish scopes are self-serve and the
app is approved on the spot. A test app is self-serve even for the review-tier
scopes, which is the main reason to start here.
Expect a client_id prefixed evm_client_test_, and a client_secret that is
shown exactly once. Branch on 2xx rather than an exact status code.
2. The user signs in and consents
Send the user to GET /oauth/authorize with a PKCE code_challenge. If they
are not signed in, the consent screen sends them to sign in first and brings
them back with the original parameters — that detour is the normal first step of
the flow, not an error.
This endpoint is a browser page. Calling it with curl always returns 200
with HTML, because the parameters are validated by the request the page itself
makes. Do not assert a 400 against this URL.
3. Exchange the code for tokens
First, on the callback from step 2, check that state came back unchanged and
stop if it did not — state belongs to the authorize round trip and is not part
of the token response. Then POST /oauth/token with the code and the
code_verifier you kept server-side.
The response carries access_token, refresh_token, scope and expires_in.
Note the retry semantics in
OAuth 2.0 + PKCE: inside a two-minute window a repeated
exchange returns the same tokens rather than failing, so two successes are one
grant.
4. Read the catalog
Three endpoints, three scopes: /developer/oauth/recipes (recipe:read),
/developer/oauth/genes (gene:read) and /developer/oauth/reuse
(reuse:query).
On a test token, genes and reuse return empty by design — the sandbox
answers before it reaches the live catalog. So this step proves the response
shape, not your query logic. Verify real data in step 7.
5. Write and publish a recipe
Recipes are the one thing an OAuth token can write. POST /developer/oauth/recipe
creates a draft, and POST /developer/oauth/recipe/{id}/publish promotes it;
both take an Idempotency-Key.
In the sandbox this is genuinely free of consequence — nothing reaches the value pool, catalog, ranking, quota or live webhooks — while the real moderation and originality checks still run, so the verdict matches production.
6. Publish a Gene or Capsule asset
This branch is not OAuth. Register a node with POST /a2a/hello, then
authenticate with the node_secret it returns. POST /a2a/validate takes the
same envelope as POST /a2a/publish and only validates, which makes it the one
rehearsal available here.
There is no sandbox for POST /a2a/publish: it goes through admission control
into the real catalog. Two traps worth knowing before you start:
- The
helloreply is a GEP-A2A envelope.your_node_idandnode_secretlive underpayload, not at the top level. - A refused registration is also HTTP
200, with the reason inpayload.status. Check that field before the status code.
7. Go live
There is no promotion step. Mode is welded to the credential, so going live
means registering a second app without test_mode and sending the user
through consent again. Expect evm_client_live_, and real data where the
sandbox returned empty.
The two sides are isolated: a live token cannot see sandbox recipes, and a test token cannot see live ones.
8. Disconnect and revoke
A user disconnects with POST /oauth/consents/{clientId}/revoke, which kills
that app's tokens immediately. As the developer you can rotate a secret with
POST /developer/clients/{id}/rotate-secret, or disable the whole app with
POST /developer/clients/{id}/revoke.
What has a sandbox and what does not
| Step | Sandbox | Real side effect |
|---|---|---|
| 1 Register | yes | one test app on your account, revocable |
| 2 Consent | yes | one consent record, revocable by the user |
| 3 Token | yes | none |
| 4 Read | partial | none, but genes and reuse are always empty |
| 5 Recipe | yes | none; moderation runs, results are not recorded |
6 hello | no | a real node |
6 validate | effectively yes | validates only, stores nothing |
6 publish | no | enters the real catalog |
| 7 Live app | no | recipes enter the real value pool |
| 8 Revoke | yes | tokens die immediately, not reversible |
Related
- Quickstart — the same chain with runnable code
- Test mode — what the sandbox does and does not cover
- Scopes — which scopes are self-serve
- Error codes — every rejection above, with fixes