Self-serve account routes
Session-authenticated routes for the signed-in user's personal Starkscan workspace and self-serve API keys.
Self-serve account routes
Use /v1/me/* when you are acting as the signed-in operator of your personal Starkscan workspace rather than as an external API-key caller.
These routes back the hosted /api-key experience and expose the same personal-workspace self-serve control plane over HTTP.
Auth
Do not send X-Starkscan-Api-Key to this lane.
Authenticate with a Better Auth session instead:
- hosted browser flow: safe reads (
GET/HEAD/OPTIONS) can use the Starkscan session cookies - server or CLI flow: send
Authorization: Bearer <better_auth_session_token>
If the session is missing or invalid, Starkscan returns 401 Unauthorized.
That body is deliberately generic and carries docSlug: "api/self-serve"; it
does not disclose whether a supplied credential was missing, expired, or
revoked. Programmatic API-key callers should discover their active scopes,
route classes, and quota contract from GET /v1/meta/capabilities's caller
object instead of calling /v1/me/*.
If you try to POST or DELETE with cookies only, Starkscan returns 403 Forbidden with a WWW-Authenticate: Bearer header.
Routes
| Route | What it does |
|---|---|
GET /v1/me/api-keys | list self-serve keys for the authenticated personal workspace |
POST /v1/me/api-keys | issue or rotate the default live read + batch + write key |
DELETE /v1/me/api-keys/{public_id} | revoke one self-serve key |
POST /v1/me/redeem-code | atomically redeem a single-use workspace-plan access code |
GET /v1/me/usage | load recent usage, failures, and per-key aggregates for the authenticated personal workspace |
Rules
GET /v1/me/api-keysreturns metadata only. It never returns plaintext secrets.GET /v1/me/api-keysreturns a bounded newest-first slice plustruncated=truewhen older historical keys exist outside the response.POST /v1/me/api-keysreturns the plaintext key once for the new or rotated default key.- If a default live key already exists,
POST /v1/me/api-keysrevokes it in the same operation and returnsaction=rotated. DELETE /v1/me/api-keys/{public_id}revokes the selected key and returns its final metadata snapshot.POST /v1/me/redeem-codeaccepts{ "code": "..." }, atomically updates the authenticated workspace plan, and consumes the code. Expired, revoked, already-used, missing, and malformed codes all return the same invalid-code error.GET /v1/me/usageis a recent operational window, not a billing export, and it surfaces truncation flags on every bounded list.POSTandDELETEon/v1/me/*are bearer-only on purpose. Starkscan rejects cookie-only mutations to avoid CSRF on key rotation/revocation.- These routes are
Cache-Control: no-storeon purpose. - Every newly issued authenticated self-serve key receives
read,batch, andwrite. There is no per-key scope picker or invite gate. Submitted scope, tier, or invite fields do not change that server-owned default. writeis an entitlement, not a promise that forwarding is active. Execution requiresrpcProvider.writeBeta.enabled, the forwarding flag, structural payload validation, a dedicated write upstream, plan rate and credit capacity, and the global kill switch. Structural validation rejects malformed payload shapes; it does not vouch for signature authority or funds.- Existing keys are not backfilled or downgraded: their stored scopes, status, and policy remain unchanged until the owner explicitly rotates or revokes them.
- Some scopes remain deliberately outside self-serve:
prove, which grants STRK20 prover relay access, andtraceare operator-issued only and are refused on this lane even if requested explicitly. Existing operator-scoped keys still appear inGET /v1/me/api-keyswith their scopes.
Examples
Export a session token if you are calling this lane outside the hosted browser:
export STARKSCAN_SESSION_TOKEN="<better_auth_session_token>"
# Optional: only set this for preview or self-hosted hosts.
# export STARKSCAN_BASE_URL="https://preview.example.com/api"List keys:
curl \
-H "Authorization: Bearer $STARKSCAN_SESSION_TOKEN" \
"${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/me/api-keys"Issue or rotate the default key:
curl -X POST \
-H "Authorization: Bearer $STARKSCAN_SESSION_TOKEN" \
"${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/me/api-keys"Revoke one key:
curl -X DELETE \
-H "Authorization: Bearer $STARKSCAN_SESSION_TOKEN" \
"${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/me/api-keys/<public_id>"Redeem a workspace-plan access code:
read -r -s STARKSCAN_ACCESS_CODE
printf '\n'
printf '%s' "$STARKSCAN_ACCESS_CODE" |
python3 -c 'import json, sys; print(json.dumps({"code": sys.stdin.read()}))' |
curl -X POST \
-H "Authorization: Bearer $STARKSCAN_SESSION_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @- \
"${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/me/redeem-code"
unset STARKSCAN_ACCESS_CODEInspect recent usage:
curl \
-H "Authorization: Bearer $STARKSCAN_SESSION_TOKEN" \
"${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/me/usage"Response shape highlights
- key list items include environment, scopes, status, masked key, rate-limit policy, and lifecycle timestamps
- issue/rotate responses include
plaintextKey,apiKey, andrevokedPublicIds - usage snapshots include:
totalRequeststotalFailuresperKeyperKeyTruncatedrecentRequestsrecentRequestsTruncatedrecentFailuresrecentFailuresTruncated
- recent usage events include request id, status, app-observed
latencyMs, API key public id, key label, key environment, and key scopes so support can trace client traffic by key/workspace without exposing secrets or raw auth-provider subject identifiers
See the API reference for the exact fields and schemas.