# Get Current Auth Context
Source: https://docs.droyd.ai/api-reference/auth/get-current-auth
api-key.openapi.json GET /v1/auth/me
Returns the active app user, entitlement, and auth method for the supplied
Droyd API key or signed-in user bearer token. This route is intended for CLI status
checks and lightweight auth diagnostics.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/auth/me`. The response never includes plaintext API keys, signed-in user access or refresh tokens. For local CLI work, run `droyd auth status --json`; if unauthenticated, ask the human to run `droyd auth login` rather than requesting credentials.
# API-Key Authentication
Source: https://docs.droyd.ai/api-reference/authentication
Authenticate an automation as one Droyd account.
Create and rotate Droyd API keys in the web app, then store each secret in your
automation's secret manager. A key acts for its owner, so every workflow,
experiment, artifact, evaluation, submission, and usage record is
automatically scoped to that account.
```bash theme={null}
curl /v1/auth/me \
-H "Authorization: Bearer $DROYD_API_KEY"
```
You can instead send `x-droyd-api-key`. Do not send both forms in the same
request. API keys are for unattended services and CI; use the CLI's browser
sign-in flow for a person working on a local workspace.
Accepted forms are `Authorization: Bearer ` and
`x-droyd-api-key: `. When `Authorization` is present it wins;
an invalid, non-Bearer, revoked, or malformed Authorization value is rejected
instead of falling back to `x-droyd-api-key`. Common failures are
`missing_authorization`, `invalid_authorization`, invalid/revoked-key errors,
and active-account or entitlement failures. Never log, persist in a workflow
file, return in an error, or place a key in a URL.
# Cancel Evaluation
Source: https://docs.droyd.ai/api-reference/benchmarks/cancel-evaluation
api-key.openapi.json POST /v1/evaluations/{id}/cancel
Cancel queued or running evaluation work.
Use this route to cancel an evaluation that has not completed. Queued work will
not start. Running hosted work is marked cancelled and its active sandbox is
terminated asynchronously.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/evaluations/{id}/cancel`. The account must own the evaluation.
Droyd records the cancellation and ends eligible non-terminal work. If the run
became terminal first, the route returns `409 evaluation_terminal`; do not
retry cancellation for a completed evaluation.
# Complete Artifact Upload
Source: https://docs.droyd.ai/api-reference/benchmarks/complete-artifact-upload
api-key.openapi.json POST /v1/artifacts/{id}/complete
Complete an uploaded experiment artifact.
Use this route after uploading all files for an artifact.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/artifacts/{id}/complete`. The completion request includes a manifest whose files must match the previously created upload intent. This route finalizes artifact metadata and hashes; do not create an agent version before completion.
For a folder, every path must match the intent and the server verifies the
stored byte count and declared SHA-256 before recording per-file rows. Folder
artifacts do not select an arbitrary primary file; provide an existing manifest
path as the entrypoint when creating the agent version.
# Create Agent Version
Source: https://docs.droyd.ai/api-reference/benchmarks/create-agent-version
api-key.openapi.json POST /v1/agent-versions
Create an immutable agent version from an artifact.
Use this route after completing an artifact upload.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/agent-versions`. Important enums: `interface` is `agent_main`, `policy_act`, `openai_compatible_endpoint`, `container`, or `custom`. For the standard single-file Python path, use `agent_main` and an uploaded `agent.py`. Folder artifacts require an explicit entrypoint that exists in the completed manifest; use the interface documented by the competition.
# Create Artifact Upload Intent
Source: https://docs.droyd.ai/api-reference/benchmarks/create-artifact-upload-intent
api-key.openapi.json POST /v1/experiments/{id}/artifacts/upload-intents
Create upload targets for an experiment artifact.
Use this route to request upload targets before uploading an agent artifact.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/experiments/{id}/artifacts/upload-intents`. Use either a `file`
artifact with exactly one root `agent.py`, or a `folder` artifact with 1–500
unique normalized POSIX relative paths. Absolute paths, `..`, empty segments,
backslashes, and duplicate paths are rejected. `archive`, `endpoint`, and
`container_image` are not accepted by this hosted route. Optional `client_key`
makes identical retries safe for the authenticated account. Use every returned
upload instruction, then call artifact completion only after every byte is
uploaded.
# Create Evaluation
Source: https://docs.droyd.ai/api-reference/benchmarks/create-evaluation
api-key.openapi.json POST /v1/evaluations
Enqueue a hosted benchmark evaluation.
Use this route to run an agent version against a competition dataset.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/evaluations`. The request requires `experiment_id`,
`agent_version_id`, and `competition_slug`; `dataset_slug` and `dataset_role`
are optional. When both are omitted, Droyd uses the competition's default
practice dataset. `workflow_node_id` marks that node `in_progress` when the
evaluation is created. Reuse `client_key` only for the same request; an
incompatible replay returns `409 client_key_conflict`.
For a public MazeBench smoke or practice run, request diagnostic feedback
explicitly with `feedback_capabilities.provider_reasoning: owner_debug` and/or
`feedback_capabilities.browser_replay: owner_debug`. The selected dataset must
publish the matching artifact contract. Droyd rejects these capabilities for
hidden and race evaluations; it never silently enables them.
`dataset_role` is one of `smoke`, `practice`, `training`, `qualifying`, or
`evaluation`. API-key evaluations can target runnable `smoke`, `practice`, and
`training` datasets only; qualifying and evaluation datasets return `403`,
including when specified by slug. `budget.concurrency` and
`budget.max_workers` are optional positive integers and must remain within the
competition limit. OpenRouter is selected by default. Supplying
`x-openrouter-api-key` or `openrouter-api-key` creates a short-lived,
evaluation-scoped credential; absent a one-off key, the account needs an active
OpenRouter credential. Missing credentials return `409 provider_credential_required`.
# Create Experiment
Source: https://docs.droyd.ai/api-reference/benchmarks/create-experiment
api-key.openapi.json POST /v1/experiments
Create a benchmark experiment.
Use this route to create the container for benchmark artifacts and evaluations.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/experiments`. Optional `competition_slug` links the experiment to a known competition. Optional `workflow_node_id` links the created experiment back to a workflow node. Optional `client_key` makes retries idempotent for the authenticated user.
# Download Evaluation Artifact
Source: https://docs.droyd.ai/api-reference/benchmarks/download-evaluation-artifact
api-key.openapi.json GET /v1/evaluations/{id}/artifacts/{artifact_id}/download
Download an artifact associated with an evaluation.
Use this route to fetch a downloadable evaluation artifact. Released
`ground_truth` artifacts are NDJSON and use a general envelope around a
competition-specific payload.
For MazeBench owner-debug runs, `provider_reasoning.jsonl` contains only
provider-emitted reasoning when available (or token counts when it is not),
with secrets and evaluator-like content redacted. `replay_manifest.json` is a
safe browser timeline; trusted replay evidence remains private.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/artifacts/{artifact_id}/download`. Both `id` and `artifact_id` are UUIDs and must be related to a caller-owned evaluation. Response content type may not be JSON; clients should follow the OpenAPI response and HTTP headers. Ground truth returns `application/x-ndjson` and is denied unless the caller owns the evaluation and its public smoke/practice dataset explicitly enables `allow_ground_truth_download`; artifact visibility alone does not override that policy.
# Get Artifact
Source: https://docs.droyd.ai/api-reference/benchmarks/get-artifact
api-key.openapi.json GET /v1/artifacts/{id}
Return one benchmark artifact.
Use this route to load artifact metadata before creating an agent version.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/artifacts/{id}`. Path `id` must be a UUID and the artifact must belong to the caller. This route returns metadata, not raw file bytes.
# Get Evaluation
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation
api-key.openapi.json GET /v1/evaluations/{id}
Return one evaluation with related links.
Use this route to poll evaluation status and discover related result endpoints.
While an evaluation is active, the response may include a `progress` snapshot:
```json theme={null}
{
"ok": true,
"evaluation": {
"id": "b870ff4a-9d50-4da2-bf15-24221efc0600",
"status": "running"
},
"progress": {
"phase": "running_tasks",
"completed": 12,
"total": 30,
"remaining": 18,
"failed": 1,
"updated_at": "2026-07-17T12:00:00Z",
"stale": false
},
"links": {}
}
```
`progress` is `null` before an attempt starts, between retry attempts, or when
an older evaluation has no progress snapshot. Poll this route about every 15
seconds. The snapshot is refreshed by the evaluation worker about every 30
seconds, so consecutive responses may contain the same counts.
`failed` counts tasks that ended with an execution error or timeout. It is not
a partial benchmark score and should not be used to predict the final result.
Final scores and result rows become available through the result endpoints
after the evaluation finishes.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/evaluations/{id}`. Status enum: `queued`, `starting`, `running`,
`ingesting`, `succeeded`, `failed`, `cancelled`, `expired`, `dead_letter`.
Terminal statuses are `succeeded`, `failed`, `cancelled`, `expired`, and
`dead_letter`. Progress phases are `preparing`, `running_tasks`, `scoring`,
`finalizing`, and `complete`. `stale: true` means the non-terminal run has not
reported fresh progress for over 90 seconds; continue polling rather than
declaring failure. Progress is aggregate-only and never contains hidden data,
prompts, outputs, or partial scores.
# Get Evaluation Sandbox Usage
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-compute-usage
api-key.openapi.json GET /v1/evaluations/{id}/usage/compute
Return Droyd sandbox runtime usage for an evaluation.
Use this route to inspect the metered CPU and memory usage recorded for one
evaluation, together with its calculated Droyd sandbox runtime cost and
redacted compute events.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/evaluations/{id}/usage/compute`. The response is
`{ ok, evaluation_id, summary, compute_usage }`; the account owns the
evaluation or receives `404`. Dependency failures return
`500 evaluation_compute_usage_load_failed`. Usage is visibility data, not a
separate payment or credit-management API.
# Get Evaluation Episodes
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-episodes
api-key.openapi.json GET /v1/evaluations/{id}/episodes
Return episode metadata for an evaluation.
Use this route to inspect individual execution episodes.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/episodes`. Episodes represent execution units within an evaluation. Use traces and logs routes for detailed execution records.
# Get Evaluation LLM Usage
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-llm-usage
api-key.openapi.json GET /v1/evaluations/{id}/usage/llm
Return redacted LLM usage for an evaluation.
Use this narrower route when an integration only needs LLM usage. The response
contains a summary and redacted event rows, not prompts, completions, API keys,
or provider request payloads.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/evaluations/{id}/usage/llm`. The response is
`{ ok, evaluation_id, summary, llm_usage_events }`. It is owner-scoped and
returns `404` for an inaccessible evaluation. Dependency failures return
`500 evaluation_llm_usage_load_failed`; retry only after normal backoff.
# Get Evaluation Logs
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-logs
api-key.openapi.json GET /v1/evaluations/{id}/logs
Return log metadata or records for an evaluation.
Use this route to inspect evaluation logs for debugging.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/logs`. Logs may include runtime output and should be handled as diagnostic data. Avoid exposing sensitive user-provided content outside the owning user's context.
# Get Evaluation Problem Results
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-problem-results
api-key.openapi.json GET /v1/evaluations/{id}/problem-results
Return per-problem result rows for an evaluation.
Use this route to inspect how an evaluation performed on individual problems.
For open datasets that publish detailed feedback, rows may include stable task
identifiers and the full entrant-visible result summary. Closed datasets return
only redacted outcomes and aggregate diagnostics such as score, gem completion,
accepted moves, token usage, model turns, provider cost, and terminal reason.
They do not return puzzle state, replay frames, per-gem action timing, or hidden
task identifiers.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/problem-results`. Prefer this route when diagnosing score variance across tasks. It is scoped to the caller-owned evaluation. When `full_artifact_access` is false, treat `score_components` and `feedback_summary` as an explicit aggregate allowlist; absence of task identity and rich result fields is intentional.
# Get Evaluation Replay
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-replay
api-key.openapi.json GET /v1/evaluations/{id}/replay
Return a browser-ready MazeBench practice replay.
Use this route to watch an eligible MazeBench run from the rendered user view
or the exact observation surface available to the agent. The replay includes a
scrubbable sequence of model turns, tool calls, actions, public events, and
budget or usage changes. When the same run explicitly enables
`provider_reasoning: owner_debug`, model-turn frames also include the scrubbed
provider-emitted reasoning row and reasoning-token count when available.
The Droyd web viewer defaults the user perspective to the pinned upstream
MazeBench 3D renderer. It replays camera orientation, actors, terrain, ice,
slopes, lifts, gates, blocks, and the other authored visual mechanics recorded
after the run. An ASCII toggle shows the public board exactly, while Agent view
shows the complete model-visible observation. Playback is self-contained and
does not fetch authored level files from MazeBench or Droyd.
Replay is owner-debug feedback. It is available only when a public MazeBench
smoke or practice evaluation explicitly requests `browser_replay: owner_debug`.
Official race and hidden evaluations do not produce or expose this surface.
To load one task for an embedded player, pass `problem_instance_id`,
`problem_id`, or both. The response then contains only the matching task. Leave
both parameters out to load the complete evaluation replay.
Auth: Droyd API key or signed-in user bearer token. The caller must own the evaluation. Alias: `GET /api/v1/evaluations/{id}/replay`.
`problem_instance_id` and `problem_id` are optional opaque-string query filters,
each limited to 200 characters. Send both when they are available. The
evaluator prefers the exact problem-instance match and uses `problem_id` only
for historical artifacts that lack instance metadata. Filtering happens before
artifact objects are read, so an inline player does not download every replay
in a practice suite.
The selected public MazeBench dataset must have role `smoke` or `practice`, must publish `replay_manifest` in its entrant-feedback policy, and the immutable evaluation `run_config.feedback_capabilities.browser_replay` must equal `owner_debug`. The response contains task manifests using `droyd.mazebench.browser_replay.v1`, content-addressed `droyd.mazebench.visual_replay.v1` render state, ordered frames, and the supported `user` and `agent` perspectives. Visual state is post-run owner feedback and was never included in model context. The response never includes evaluator state hashes, hidden scoring state, scorer inputs, credentials, system or validator prompts, solution traces, or trusted replay evidence.
If the dataset also publishes `provider_reasoning` and the immutable run capability equals `owner_debug`, each task includes its validated `droyd.mazebench.provider_reasoning.v1` rows for correlation by `model_turn_id`. Models that do not emit open reasoning remain valid and return `available: false`, with `reasoning_tokens` populated when the provider reports only a count. Reasoning is diagnostic and was not fed into later turns.
`400 replay_task_selector_invalid` means a task filter is empty or too long.
`403 replay_not_available` means the dataset, mode, policy, or immutable capability does not authorize replay. `404 replay_not_ready` means an eligible evaluation has no published replay yet; `404 replay_task_not_found` means no published artifact matched the requested task; an unknown or non-owned evaluation also returns `404`. `422 replay_manifest_invalid`, `replay_manifest_private_field`, `replay_visual_state_invalid`, `replay_artifact_too_large`, `provider_reasoning_invalid`, or `provider_reasoning_artifact_too_large` means a published owner-debug artifact failed the public safety contract. Do not retry those `422` responses as transient storage failures.
# Get Evaluation Results
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-results
api-key.openapi.json GET /v1/evaluations/{id}/results
Return summary result rows for an evaluation.
Use this route to retrieve scored evaluation result summaries.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/results`. Use after an evaluation reaches a terminal status. For per-problem detail, use `/problem-results`; for raw traces and logs, use the trace/log routes.
# Get Evaluation Traces
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-traces
api-key.openapi.json GET /v1/evaluations/{id}/traces
Return trace metadata or records for an evaluation.
Use this route to inspect evaluation trajectory data.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/traces`. Trace payloads can be large or object-storage backed depending on the evaluation. Do not assume every trace is inline JSON.
# Get Evaluation Usage
Source: https://docs.droyd.ai/api-reference/benchmarks/get-evaluation-usage
api-key.openapi.json GET /v1/evaluations/{id}/usage
Return combined LLM and Droyd sandbox usage for an evaluation.
Use this route to inspect the combined usage record for one evaluation. It
returns LLM and Droyd sandbox summaries with redacted event detail, making it
useful for comparing runs without exposing credentials or model input/output.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/evaluations/{id}/usage`. The evaluation must be owned by the
authenticated account; inaccessible IDs return `404`. The response has
`evaluation_id`, `llm`, `compute`, `llm_usage_events`, and
`compute_usage`. Treat totals as the currently recorded usage for the run,
not as a balance or a payment instruction. The `compute` summary includes the
calculated customer cost plus CPU, memory, and GPU cost splits;
its resource-time fields use CPU core-seconds, memory GiB-seconds, and GPU
seconds. These values are provisional, and a record can remain unavailable while its
cost is still being calculated. `500` uses a route-specific usage-load error
code when its dependencies cannot be read.
# Get Experiment
Source: https://docs.droyd.ai/api-reference/benchmarks/get-experiment
api-key.openapi.json GET /v1/experiments/{id}
Return one benchmark experiment.
Use this route to load experiment metadata before listing artifacts or evaluations.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/experiments/{id}`. Path `id` must be a UUID and the experiment must belong to the caller. Missing or unauthorized records return a not-found style response.
# List Evaluation Artifacts
Source: https://docs.droyd.ai/api-reference/benchmarks/list-evaluation-artifacts
api-key.openapi.json GET /v1/evaluations/{id}/artifacts
List artifacts produced or associated with an evaluation.
Use this route to find downloadable score reports, traces, logs, ground truth
released for open problem sets, or related artifacts. Ground truth is not
available for private or closed datasets.
MazeBench owner-debug runs may also return `reasoning`, `replay`, and a single
ZIP feedback bundle. These appear only for public smoke/practice datasets when
the immutable run requested the matching `owner_debug` capability.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/evaluations/{id}/artifacts`. Some artifact kinds are used as detailed datasets or score summaries. Use the artifact download route for file bytes when a returned artifact is downloadable. A `ground_truth` row is returned only for a public smoke/practice dataset whose policy explicitly sets `allow_ground_truth_download: true`. Its NDJSON rows use the shared `droyd.eval_ground_truth.v1` envelope; interpret `ground_truth.payload` using `competition_slug` and `ground_truth.schema_id`, because the payload is competition-native. Absence means ground truth was not released, not that the answer was empty.
# List Experiment Artifacts
Source: https://docs.droyd.ai/api-reference/benchmarks/list-experiment-artifacts
api-key.openapi.json GET /v1/experiments/{id}/artifacts
List artifacts uploaded for an experiment.
Use this route to show uploaded artifacts attached to an experiment.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/experiments/{id}/artifacts`. Results are scoped to caller ownership and ordered newest first. For evaluation output artifacts, prefer the evaluation artifact routes.
# List Experiment Evaluations
Source: https://docs.droyd.ai/api-reference/benchmarks/list-experiment-evaluations
api-key.openapi.json GET /v1/experiments/{id}/evaluations
List evaluations for an experiment.
Use this route to show the evaluation history for an experiment.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/experiments/{id}/evaluations`. Results are scoped to the caller and ordered newest first. Use individual evaluation routes to fetch result tables, traces, logs, and artifact links.
# Complete payment method setup
Source: https://docs.droyd.ai/api-reference/billing/complete-payment-method-setup
api-key.openapi.json POST /v1/billing/payment-method/complete
Save a successfully configured card for the authenticated account.
After Stripe confirms card setup, send the returned SetupIntent ID:
```json theme={null}
{
"setup_intent_id": "seti_..."
}
```
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/billing/payment-method/complete`. `setup_intent_id` must begin
with `seti_`, belong to this account, have succeeded, and contain a card with a
billing address. Do not call this route before the client-side Stripe flow
finishes. A conflicting ownership or state check is rejected.
# Create a top-up
Source: https://docs.droyd.ai/api-reference/billing/create-top-up
api-key.openapi.json POST /v1/billing/top-ups
Purchase prepaid evaluation funds.
Purchase `$5.00`–`$500.00` of prepaid funds by sending a decimal USD string:
```json theme={null}
{
"amount_usd": "25.00"
}
```
The response is `200` if payment has already completed or `202` while it is
pending. Funds are not spendable until the status is `paid`.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/billing/top-ups`. Requires an `Idempotency-Key` header of 8–120
URL-safe characters. `amount_usd` must be a decimal string from `5.00` through
`500.00` with at most two fractional digits. Reuse the same key only for the
same amount. The caller must already have a saved payment method.
Statuses are `pending`, `payment_pending`, `action_required`, `paid`, `failed`,
or `cancelled`. If `action_required`, use the transient client secret with
Stripe's SDK and then poll the returned URL.
# Billing credits
Source: https://docs.droyd.ai/api-reference/billing/credits
api-key.openapi.json GET /v1/billing/balance
Read credit balances and manage prepaid account funding.
Billing endpoints use the authenticated account as the billing owner. Monetary
request and response values are decimal USD strings.
| Method | Path | Purpose |
| ------ | ------------------------------------- | ----------------------------------------------------------------- |
| `GET` | `/v1/billing/balance` | Return the spendable balance and active promotional or paid lots. |
| `GET` | `/v1/billing/transactions` | Return recent credit-ledger activity. |
| `GET` | `/v1/billing/invoices` | Return recent Stripe payment receipts. |
| `POST` | `/v1/billing/payment-method/setup` | Start secure card setup and return a Stripe client secret. |
| `POST` | `/v1/billing/payment-method/complete` | Confirm that card setup completed for this account. |
| `POST` | `/v1/billing/top-ups` | Purchase `$5.00`–`$500.00` of prepaid funds. |
| `GET` | `/v1/billing/top-ups/:purchaseId` | Poll one top-up owned by the caller. |
| `GET` | `/v1/billing/auto-top-up` | Read the automatic top-up policy. |
| `PUT` | `/v1/billing/auto-top-up` | Enable, disable, or update automatic top-up. |
Top-ups and automatic-top-up changes require an `Idempotency-Key` header.
Top-up presets are `$5`, `$25`, `$100`, and `$500`; custom amounts from `$5.00`
through `$500.00` are accepted. Automatic top-up is opt-in and defaults to
recharging the balance to `$25.00` when it reaches `$5.00`.
A top-up may return `202` while payment is pending. Poll its returned URL until
the status is `paid`, `failed`, or `action_required`. Funds are not spendable
until payment succeeds.
Auth: Droyd API key or signed-in user bearer token. Every path also accepts the
`/api/v1` compatibility prefix. The caller cannot supply a user or customer ID.
Mutation endpoints return `503 billing_mutations_disabled` while account
funding is unavailable in the target environment.
`Idempotency-Key` must be 8–120 URL-safe characters. `amount_usd`,
`threshold_usd`, and `recharge_to_usd` must be decimal strings with no more than
two fractional digits. One-time top-ups must be `$5.00`–`$500.00`. Enabled
automatic top-up requires a saved payment method, a threshold of at least
`$5.00`, and a recharge target at least `$10.00` above the threshold.
Card setup is a two-step Stripe SetupIntent flow. Pass the first response's
`client_secret` only to Stripe's client SDK; do not log or persist it. After
Stripe reports success, send its `setup_intent_id` to the completion endpoint.
The automatic-top-up read response may include the saved card's brand, last
four digits, expiration, and non-sensitive billing details so account UIs can
show what is configured. Full card data is never returned.
The balance is authoritative and may return `404 billing_account_not_found`
before account provisioning. Billing or database dependency failures return a
sanitized `503 billing_unavailable`; credentials, raw billing responses, and
internal billing identifiers are not exposed.
# Get automatic top-up
Source: https://docs.droyd.ai/api-reference/billing/get-auto-top-up
api-key.openapi.json GET /v1/billing/auto-top-up
Return the automatic top-up policy for the authenticated account.
Returns whether automatic top-up is enabled, its balance threshold, its
recharge target, and whether a payment method is ready. When a saved card is
available, `payment_method` contains its brand, last four digits, expiration,
and non-sensitive billing details. It never contains card numbers or Stripe
client secrets.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/billing/auto-top-up`. The account is derived from authentication.
Automatic top-up is opt-in and is off until explicitly enabled.
`payment_method` is `null` when no saved card is configured.
# Get a top-up
Source: https://docs.droyd.ai/api-reference/billing/get-top-up
api-key.openapi.json GET /v1/billing/top-ups/{purchaseId}
Poll one caller-owned top-up.
Returns the current state of one top-up created by the authenticated account.
Poll until the status is `paid`, `failed`, or `cancelled`, or handle
`action_required` with Stripe's client SDK.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/billing/top-ups/{purchaseId}`. `purchaseId` must be a UUID. A
missing purchase and a purchase owned by another account both return a
not-found response. This route performs billing read-back before responding.
# List payment receipts
Source: https://docs.droyd.ai/api-reference/billing/list-invoices
api-key.openapi.json GET /v1/billing/invoices
Return recent Stripe payment receipts for the authenticated account.
Returns successful Stripe charges that have a hosted receipt for the
authenticated billing account. Metronome draft usage invoices and scheduled
prepaid-credit accounting entries are not customer documents and are omitted.
Use `limit` to return 1–100 entries; the default is 50.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/billing/invoices`. The account is derived from authentication.
`limit` must be one integer value from 1 through 100. Payment state can change;
use the returned top-up poll URL for one purchase workflow. The route path is
retained for compatibility even though the returned documents are Stripe
receipts.
# List billing transactions
Source: https://docs.droyd.ai/api-reference/billing/list-transactions
api-key.openapi.json GET /v1/billing/transactions
Return recent credit additions and deductions.
Returns recent activity for the authenticated account's promotional and
purchased credit lots. Customer-facing activity types distinguish one-time
credit purchases, automatic top-ups, promotional credits, usage, expirations,
rollovers, and adjustments. Use `limit` to return 1–100 entries; the default is
50\.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/billing/transactions`. The account is derived from authentication.
`limit` must be one integer value from 1 through 100. This is a read-only ledger
view, not an account balance or purchase-status endpoint. `activity_type` is
the stable customer-facing classification. Credit funding and lifecycle rows
are sourced from Metronome; evaluation-usage rows use Droyd's successfully
delivered usage event so `occurred_at` reflects when the evaluation consumed
credits rather than a future invoice-effective date. `transaction_type`
preserves the source event classification for diagnostics and must not be
displayed directly to end users.
# Start payment method setup
Source: https://docs.droyd.ai/api-reference/billing/start-payment-method-setup
api-key.openapi.json POST /v1/billing/payment-method/setup
Create a secure card-setup session for the authenticated account.
Starts card setup and returns a Stripe SetupIntent client secret. Pass that
secret directly to Stripe's client SDK. Do not log or persist it.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/billing/payment-method/setup`. Requires an `Idempotency-Key`
header of 8–120 URL-safe characters. This route lazily creates the caller's
billing-customer linkage when needed. It does not add spendable funds.
After Stripe reports success, call the completion route with the SetupIntent ID.
# Update automatic top-up
Source: https://docs.droyd.ai/api-reference/billing/update-auto-top-up
api-key.openapi.json PUT /v1/billing/auto-top-up
Enable, disable, or change automatic prepaid funding.
Automatic top-up is off by default. Enable it with the default `$5.00`
threshold and `$25.00` recharge target:
```json theme={null}
{
"enabled": true
}
```
You can also provide `threshold_usd` and `recharge_to_usd` as decimal strings.
Auth: Droyd API key or signed-in user bearer token. Alias:
`PUT /api/v1/billing/auto-top-up`. Requires an `Idempotency-Key` header of
8–120 URL-safe characters. `enabled` is required and must be boolean. Monetary
values allow at most two fractional digits. When enabled, the threshold must be
at least `5.00`, the recharge target must be at least `10.00` above it, and the
account must have a saved payment method. Disabling preserves the configured
amounts for later reuse.
# POST /v1/competitions/{slug}/configure-credentials
Source: https://docs.droyd.ai/api-reference/competitions/configure-credentials
api-key.openapi.json POST /v1/competitions/{slug}/configure-credentials
Configure a competition-specific credential for API-key automation.
Configure a credential required by a competition. For ORO, this registers an
OpenRouter management key for the selected Bittensor wallet.
Auth: Droyd API key or signed-in user bearer token plus active app state. Alias:
`POST /api/v1/competitions/{slug}/configure-credentials`.
Body: `credential_type` is required. Currently supported:
`openrouter_management` for ORO. Provide exactly one of `api_key` or
`credential_id`. `wallet_id` is required for ORO. `label` and `metadata` are
optional when storing a new `api_key`.
OpenRouter management keys must begin with `sk-or-v1-` and are limited to 8192
characters.
ORO requirements: include signed local Bittensor headers `X-Hotkey`,
`X-Timestamp`, `X-Nonce`, and `X-Signature`. Droyd validates that `X-Hotkey`
matches the selected Droyd-registered Bittensor wallet, stores or decrypts the
OpenRouter management key server-side, forwards `{ credential }` to ORO
`POST /v1/miner/inference-auth/openrouter`, then makes OpenRouter the default
through `PATCH /v1/miner/inference-auth/default`. The PATCH uses a second signed
envelope supplied as `X-Droyd-Oro-Default-Provider-Hotkey`,
`X-Droyd-Oro-Default-Provider-Timestamp`,
`X-Droyd-Oro-Default-Provider-Nonce`, and
`X-Droyd-Oro-Default-Provider-Signature`; its nonce must differ from the primary
`X-Nonce`. Droyd records
`competition_provider_connections` with the synced credential id. ORO preflight
requires that id to match the currently active Droyd management credential and
blocks if OpenRouter is no longer the ORO default.
The response returns credential and connection metadata only. It never returns
plaintext secrets, encrypted ciphertext, raw signatures, or raw nonces. API-key
callers can configure competition credentials but cannot read stored secret
material back.
# Confirm Race Payment
Source: https://docs.droyd.ai/api-reference/competitions/confirm-race-payment
api-key.openapi.json POST /v1/competitions/{slug}/races/{race_id}/payments/{payment_intent_id}/confirm
Verify and record a client-signed devnet race payment.
Use this route after the client signs and sends the payment transfer itself.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/competitions/{slug}/races/{race_id}/payments/{payment_intent_id}/confirm`.
The JSON body is `{ "signature": "..." }` with an 87–88 character base58
Solana Ed25519 signature. The server requires a successful transaction at
configured finality.
For protocol v3, the transaction must contain the one exact released
`race_entry` instruction, with only approved Compute Budget instructions
alongside it. Confirmation also loads the deterministic entry-receipt PDA and
matches its race, entry UUID, participant wallet, source ATA, amount, and
canonical submission-manifest hash. Legacy races retain the exact classic SPL
Token `transferChecked` plus memo verification contract. Chain block time must
be at or before expiry.
Confirmation stores immutable verification evidence and atomically marks the
payment `confirmed`, race entry `paid`, and benchmark submission `paid`. A v3
entry also exposes `submission_manifest_hash`, `entry_receipt_pda`, and
`entry_receipt_verified_at`. The same fully evidenced confirmed signature
replays; conflicting, ambiguous, expired, missing-receipt, or reused
signatures return stable errors. A confirmed replay returns the stored funded
ledger and does not re-verify or credit the vault a second time.
`x402` intents return `501 x402_payment_disabled`. Do not call this endpoint
before broadcasting the transaction. Verification failures never invoke the
confirmation RPC. A dependency failure returns a stable sanitized message;
database and Solana RPC diagnostics are not copied into the response.
# POST /v1/competitions/{slug}/preflights
Source: https://docs.droyd.ai/api-reference/competitions/create-preflight
api-key.openapi.json POST /v1/competitions/{slug}/preflights
Run submission checks for an immutable competition candidate.
Run submission preflight checks for an uploaded experiment artifact before
submitting it to a competition.
Auth: Droyd API key or signed-in user bearer token plus active app state. Alias:
`POST /api/v1/competitions/{slug}/preflights`. Body requires
`experiment_id`, `agent_version_id`, and `artifact_id`; accepts
`workflow_node_id`, `wallet_id`, user-scoped `client_key`, `checks`, and
`metadata`. `client_key` is idempotent per user. Supported `checks` values are
`static`, `provider`, and `llm`; ORO implements all three. For ORO, static
checks verify uploaded artifact state,
root `agent.py`, the 1,000,000-byte limit, UTF-8, Python syntax, the
single top-level `agent_main(problem_data)` signature, prohibited imports/calls,
file writes, and exact active-suite reward identifiers, long reward-title
content, or distinctive query phrases. Suite-content findings are advisory and
set `details.requires_confirmation=true`.
The ORO `llm` check uses a structured semantic review focused on hardcoded
product ids/names, suite queries, answer lookup tables, hidden reward access,
and encoded answer data. It does not score plagiarism similarity. No
medium/major finding passes; medium/major findings or review unavailability
return an advisory warning with `requires_confirmation=true`.
ORO `provider` checks require locally signed
`X-Hotkey`, `X-Timestamp`, `X-Nonce`, and `X-Signature` headers plus
`wallet_id`; they verify the stored OpenRouter management credential, live ORO
OpenRouter inference-auth state, a successful sync for the currently active
Droyd credential, signed header ownership, provider auth/subnet readiness, that
OpenRouter is ORO's default inference provider, and ORO's authoritative
`can_submit` cooldown state from `GET /v1/miner/agents`. The cooldown request
requires a second, distinct signed envelope in
`X-Droyd-Oro-Cooldown-Hotkey`, `X-Droyd-Oro-Cooldown-Timestamp`,
`X-Droyd-Oro-Cooldown-Nonce`, and `X-Droyd-Oro-Cooldown-Signature`; its nonce
must differ from `X-Nonce`. A passing provider preflight is wallet-bound and
expires after five minutes. Final submit requires another new signature and
nonce.
For NOVA Blueprint, request `checks: ["static", "provider"]` and pass the
caller-owned local Bittensor `wallet_id`. Static checks require a folder
artifact with root `miner.py`, safe deterministic-ustar paths, no recognized
secret material, no more than 500 files, and no more than 16 MiB uncompressed.
Provider checks use Taostats for SN68 registration and the live MetaNova
`/quote`. The response includes `nova_submission_quote` and
`nova_slot_occupancy`; clients must display the quote and assume an existing
slot may be replaced when occupancy is unavailable. The passed preflight is
bound to the exact competition, experiment, version, artifact, and wallet and
expires after five minutes.
# Create Paid Race Submission
Source: https://docs.droyd.ai/api-reference/competitions/create-race-submission
api-key.openapi.json POST /v1/competitions/{slug}/races/{race_id}/submissions
Create or replay a Droyd Solana race entry and payment intent.
Create a race entry after uploading an agent artifact. The response tells the
client exactly which devnet transaction funds the entry.
Auth: Droyd API key or signed-in user bearer token. Alias:
`POST /api/v1/competitions/{slug}/races/{race_id}/submissions`. Required body
fields are `experiment_id`, `agent_version_id`, `artifact_id`, and `wallet_id`.
The experiment, version, artifact, visible competition, race, and caller-owned
Solana wallet must agree. The wallet must have `environment=devnet`.
`payment_method` defaults to and currently accepts only
`embedded_wallet_spl`; `x402` is declared for future storage compatibility but
returns `501 x402_payment_disabled` before ledger creation. A non-empty
`client_key` is scoped to `(user, race)` and binds the canonical request. An
exact replay returns the original entry and intent with `200`; a new entry
returns `201`; reusing the key for different content returns
`409 idempotency_conflict`. The same text key may create an independent entry
in a different race because race ID is part of the scope and fingerprint.
The response `payment.type` is `spl_transfer` for legacy races and
`race_entry` for protocol v3. Preserve every returned field exactly. A v3
payment identifies the released race program, race PDA, entry UUID, canonical
submission-manifest hash, mint, amount, source wallet, and destination vault;
it has no memo because the program binds the entry and manifest on-chain.
Build or submit the transaction through the Droyd SDK/CLI so sponsorship and
the hosted-wallet signature use the reviewed template.
Malformed JSON, missing or mistyped UUID fields, unsupported payment methods,
and empty optional keys return `400 invalid_request`. Closed races return
`409 race_not_open`; unowned or non-devnet wallets share the non-disclosing
`wallet_not_devnet_solana` contract.
# POST /v1/competitions/{competition_id_or_slug}/submissions/create
Source: https://docs.droyd.ai/api-reference/competitions/create-submission
api-key.openapi.json POST /v1/competitions/{competition_id_or_slug}/submissions/create
Requires competition lifecycle state live. Practice mode keeps skills, datasets, and evaluations available but returns 409 competition_submissions_closed from this route.
Submit an uploaded agent artifact to a competition.
Auth: Droyd API key or signed-in user bearer token. Canonical route:
`POST /v1/competitions/{competition_id_or_slug}/submissions/create`.
Aliases:
`POST /api/v1/competitions/{competition_id_or_slug}/submissions/create`,
`POST /v1/competitions/{competition_id_or_slug}/submissions`, and
`POST /api/v1/competitions/{competition_id_or_slug}/submissions`. Body requires
`experiment_id`, `agent_version_id`, and `artifact_id`. `client_key` is
user-scoped idempotency. `workflow_node_id` links the submission back to a
workflow node.
The competition lifecycle must be `live`. A competition in `practice` exposes
its skill, datasets, and evaluations but rejects this route with
`409 competition_submissions_closed` until race mode opens.
Droyd-hosted competitions enqueue a hosted evaluation and return
`evaluation_id`, `job_id`, and `poll_url`. External provider competitions may
return those fields as null/omitted and include `external_submission` plus
`provider_submission`. For ORO, `poll_url` points to the live provider-status
adapter and `poll_after_ms` is 15000. Follow that URL until the returned
`status.terminal` is true; do not poll the released submission-detail route.
For first-party Droyd race competitions, pass the caller-owned Solana devnet
`wallet_id`. Pass the optional top-level `race_id` to choose a race; a
`race_id` inside `metadata` is never used for selection. If top-level
`race_id` is omitted, submission succeeds only when exactly one configured
race is currently open. Zero open races return `409 no_open_race`; multiple
open races return `409 ambiguous_open_race`. The API atomically creates or
replays the shared submission, race entry, and embedded-wallet SPL payment
intent. Race responses include typed `entry`, `payment_intent`, and `payment`
instructions. `payment.type` is `spl_transfer` for legacy races and
`race_entry` for protocol v3. The v3 shape binds the released program, race
PDA, entry UUID, and canonical submission-manifest hash; it does not use a
memo. Compatible race-scoped `client_key` retries return the original ledger
with HTTP 200; changed requests return `409 idempotency_conflict`.
For ORO, pass `wallet_id` for the caller-owned registered local Bittensor
wallet and a passed `preflight_id` from `POST /v1/competitions/oro/preflights`.
The preflight must include provider checks, match the same wallet and artifact,
contain all required ORO checks, and be no more than five minutes old.
The request must include locally signed ORO headers `X-Hotkey`, `X-Timestamp`,
`X-Nonce`, and `X-Signature`; the API verifies that `X-Hotkey` matches the
selected wallet and forwards the signed provider request to ORO. Use a new
signature and nonce; the preflight signature cannot be replayed. `agent_name`
is optional and defaults to the experiment title when possible. Before
forwarding, Droyd verifies that the current `agent.py` bytes still match the
SHA-256 recorded when the artifact upload completed. Hosted
Bittensor wallet signing currently returns `501 hosted_bittensor_submission_todo`.
For NOVA Blueprint, pass the same candidate and local Bittensor `wallet_id`
used by a passed provider preflight, plus a required `client_key`. The CLI
builds the deterministic `submission/` tar.gz and sends only `X-Hotkey`,
`X-Code-Hash`, and `X-Signature`; the API rebuilds the archive from the stored
artifact and rejects any hash/signature mismatch. Pass
`X-Nova-Overwrite-Confirmed: true` because MetaNova has one mutable epoch slot.
Also pass `X-Nova-Charge-Confirmed: true` unless the current preflight quote is
explicitly free. A provider timeout, reset, HTTP 408, or 5xx returns HTTP 202
with `status="outcome_unknown"`,
`outcome.provider_retry_safe=false`, and
`outcome.client_replay_safe=true`. Retry only with the identical `client_key`
to read the durable Droyd receipt; never create a fresh submission. Nova
returns `poll_url=null` while asynchronous provider-result reconciliation is
pending. If the AWS ingestion registration fails after MetaNova accepts, the
API returns a registration-specific error but preserves the accepted receipt;
repeat the identical request/client key to retry only registration.
# Get Race Submission Status
Source: https://docs.droyd.ai/api-reference/competitions/get-race-submission-status
api-key.openapi.json GET /v1/competitions/{slug}/races/{race_id}/submissions/{submission_id}/status
Return a caller-owned race entry and its payment intent.
Poll this route after creating an entry or sending its payment.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/competitions/{slug}/races/{race_id}/submissions/{submission_id}/status`.
All identifiers are ownership-scoped and cross-race or cross-user lookups
return `404`. Entry statuses are `payment_pending`, `paid`,
`qualifier_queued`, `qualifying`, `qualified`, `final_queued`,
`final_evaluating`, `evaluated`, `finalized`, `ineligible`, `rejected`,
`cancelled`, `refunding`, or `refunded`. Payment statuses are `created`,
`submitted`, `confirmed`, `failed`, `expired`, or `cancelled`. Treat
`confirmed` payment plus `paid` entry as the atomic funded state. Non-success
payment states may include an allowlisted `failure_code` and sanitized
`failure_message` for retry decisions. Successful confirmation always projects
both fields as `null`; raw provider, RPC, wallet, and database diagnostics are
never returned. Protocol-v3 entries additionally expose the canonical
`submission_manifest_hash` and, after confirmation, the verified
`entry_receipt_pda` and `entry_receipt_verified_at`.
# GET /v1/competitions/{slug}/registration/status
Source: https://docs.droyd.ai/api-reference/competitions/get-registration-status
api-key.openapi.json GET /v1/competitions/{slug}/registration/status
Check registration state for a caller-owned competition wallet.
Check the caller's selected Bittensor wallet registration status for a
competition subnet.
Auth: Droyd API key or signed-in user bearer token plus active app state. Alias:
`GET /api/v1/competitions/{slug}/registration/status`. Optional query:
`wallet_id=`. For Bittensor subnet competitions, the response includes
`required`, `netuid`, `wallet_id`, `hotkey_address`, `registered`, `status`,
and `next_actions`. Without provider headers, the route returns cached state or
`unknown`. Supplying fresh `X-Hotkey`, `X-Timestamp`, `X-Nonce`, and
`X-Signature` headers performs a live ORO miner check, persists the result, and
returns `registered` or `not_registered`. An ORO `401` returns `auth_failed`
with `registered: null`; it does not cache a registration failure. Each
signature and nonce is single-use. ORO can cache chain registration for up to
five minutes, so an immediate post-transaction `not_registered` result should
be checked again after that window rather than triggering a second registration.
# Get Competition Requirement Status
Source: https://docs.droyd.ai/api-reference/competitions/get-requirements-status
api-key.openapi.json GET /v1/competitions/requirements/status
Check the signed-in user's credential and registration readiness for one or more competitions.
Return a personalized readiness checklist for competition and workflow pages.
Each competition includes a completed count, an overall state, credential
details, and Bittensor registration status and cost when applicable.
Use the optional `slugs` query to check several competitions in one request:
```text theme={null}
GET /v1/competitions/requirements/status?slugs=oro,nova-blueprint,negotiation
```
Credential values are never returned. Add `include_cost=true` when opening a
detailed view to load Bittensor registration cost in TAO and, when current
price data is available, USD. Add `include_registration=true` to resolve owned
hotkeys against the current Taostats metagraph. Omit both for a faster
badge-only read.
Current requirements are:
* Negotiation: `OPENROUTER_API_KEY`.
* Nova Blueprint: an active Bittensor registration on subnet 68.
* ORO: `OPENROUTER_API_KEY`, `OPENROUTER_MANAGEMENT_KEY`, and an active
Bittensor registration.
Auth: Droyd API key or signed-in user bearer token plus active app state. Alias:
`GET /api/v1/competitions/requirements/status`. `slugs` is an optional
comma-separated list; values are trimmed, deduplicated, validated, and limited
to 50. Omit it to load all visible, non-archived competitions. Unknown, hidden,
or archived requested slugs do not produce synthetic rows.
`include_cost` accepts `true`, `false`, `1`, or `0` and defaults to false. The
same values are accepted by `include_registration`, which also defaults to
false. With both defaults, the route does not call Taostats or CoinGecko and
returns `cost: null`.
Summary states are `complete`, `partial`, `missing`, and `not_required`.
Summary counts include required definitions only. Credential requirements match
an active caller-owned `user_default` credential by exact provider and
`secret_name`; returned credential data is safe metadata only. Bittensor
requirements return `registered`, `not_registered`, `unknown`, or
`wallet_missing` from caller-owned cached registration and wallet records.
With `include_registration=true`, every owned hotkey is checked through the
Taostats latest metagraph endpoint; all lookups must succeed before an empty
result becomes `not_registered`. Provider failures fall back to cached
evidence. This route never performs a signed ORO check. Use the signed
`GET /v1/competitions/{slug}/registration/status` workflow to refresh the
persisted registration evidence. Positive and negative checks are current for
24 hours; stale or invalid timestamps return `unknown`. Any owned wallet with
fresh positive evidence can satisfy this account-level requirement. The route
returns `not_registered` only when every owned Bittensor wallet has fresh
negative evidence, and includes the selected evidence wallet in the response.
With `include_cost=true`, registration cost uses Taostats for rao/TAO and the
cached CoinGecko TAO price for USD. If Taostats fails, `cost` is null. If only
pricing fails, TAO remains available while `amount_usd`, `price_usd`, and price
provenance are null. Cost enrichment does not change readiness.
Empty/malformed `slugs`, `include_cost`, or `include_registration` returns `400 invalid_request`; auth
failures return `401` or `403`; required database read failures return a
structured `500`.
# GET /v1/competitions/{slug}/setup/status
Source: https://docs.droyd.ai/api-reference/competitions/get-setup-status
api-key.openapi.json GET /v1/competitions/{slug}/setup/status
Check a caller's wallet, credential, registration, and blocker state.
Check whether the signed-in user has the wallet, credential, provider
connection, and registration setup needed for a competition.
Auth: Droyd API key or signed-in user bearer token plus active app state. Alias:
`GET /api/v1/competitions/{slug}/setup/status`. Optional query:
`wallet_id=`. If `wallet_id` is omitted, the API checks the most recent
caller-owned Bittensor wallet. Secret values are never returned. For ORO,
`credentials.openrouter_management.present` reports whether an
`OPENROUTER_MANAGEMENT_KEY` exists in stored credentials, and
`external_connections.oro_openrouter.status` reports the last recorded ORO
connection state. Unsigned setup reads use the most recently persisted live ORO
registration check and may return `unknown` before one has been run. Use the
registration-status route with fresh signed ORO headers for a live check.
# List My Race Payouts
Source: https://docs.droyd.ai/api-reference/competitions/list-race-payouts
api-key.openapi.json GET /v1/competitions/{slug}/races/{race_id}/payouts
Discover your payout items and whether each one can be claimed.
Use this route after a race closes to find winnings or cancelled-race refunds,
their claim deadlines, and any claim already in progress.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/competitions/{slug}/races/{race_id}/payouts`. Results are strictly
caller-owned and ordered by payout-item `created_at DESC, id DESC`.
Pagination uses integer `limit` and `offset`; `limit` defaults to `25`, must be
`1..100`, and `offset + limit` must not exceed `100000`. Follow
`page.has_more` and `page.next_offset`.
Each result includes `settlement_kind` (`payout` or `refund`), the immutable
amount and recipient wallet/token-account snapshot, item status, claim-window
timestamps, derived claimability, and the latest claim when one exists.
Refund items belong only to a race with `status=cancelled` and
`cancellation_kind=refund`; they are never competitive winnings. Claimability
states are `claimable`,
`claim_in_progress`, `claimed`, `forfeited`, `race_not_finalized`,
`manifest_not_finalized`, `payout_state_unavailable`, `claim_not_open`,
`claim_window_closed`, or `claim_window_unavailable`. Claimability requires a
finalized race for payouts, or a published funded-cancellation refund
settlement for refunds, plus a finalized or published referenced manifest. The
claim window is inclusive at both endpoints. This read supports either bearer auth or
an API key, but claim preparation and hosted signing remain signed-in-user-only
actions.
The response never contains Merkle leaves/proofs, private manifest or series
metadata, hosted-wallet provider IDs, encrypted fields, other users, or raw
dependency failure details. Use the payout status together with
`latest_claim.status`; do not treat a missing claim as claimable unless
`claimability.claimable` is true.
When `latest_claim` is non-successful it may include an allowlisted
`failure_code` and sanitized `failure_message`. These fields never contain raw
Privy, Solana RPC, wallet, transaction, credential, or database payloads, and
they are `null` after successful confirmation.
# List My Race Submissions
Source: https://docs.droyd.ai/api-reference/competitions/list-race-submissions
api-key.openapi.json GET /v1/competitions/{slug}/races/{race_id}/submissions
List your entries, linked submissions, and current payment state for one race.
Use this route to restore a paid-race workflow after an interruption and decide
whether each entry still needs payment, confirmation, or evaluation polling.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/competitions/{slug}/races/{race_id}/submissions`. Results are
strictly caller-owned and ordered by entry `created_at DESC, id DESC`.
Pagination uses integer `limit` and `offset`; `limit` defaults to `25`, must be
`1..100`, and `offset + limit` must not exceed `100000`. Use `page.has_more`
and `page.next_offset` instead of inferring another page from item count.
Each item contains the race entry, a sanitized linked benchmark-submission
summary, and `latest_payment_intent`. The current ledger permits one payment
intent per entry, so that object is the authoritative resume record. Payment
statuses are `created`, `submitted`, `confirmed`, `failed`, `expired`, or
`cancelled`. A non-success intent may carry an allowlisted `failure_code` and
sanitized `failure_message`, including a retryable diagnostic while a signed
intent remains `submitted`. Confirmed intents project both fields as `null`.
Protocol-v3 entry projections include their canonical
`submission_manifest_hash` and verified receipt identity/timestamp. Use these
fields as read-only evidence; do not derive a replacement payment transaction
from them.
The route never returns other users, private competition/series
metadata, hosted-wallet provider IDs, encrypted fields, or raw dependency
failure details. Missing linked ledger rows fail closed with `500` instead of
returning a partial item.
# Idempotency and Polling
Source: https://docs.droyd.ai/api-reference/idempotency-and-polling
Safely retry writes and follow asynchronous work.
Use a unique `client_key` for a logical create request whenever the route
accepts one. Reuse the same key only to retry the identical work. A successful
replay returns the resource already created; a key reused for different input
returns a conflict instead of creating ambiguous work.
Creating an evaluation, submission, or race entry starts work that may finish
later. Store the returned IDs, then poll that resource's status endpoint with
backoff until it reaches a terminal state. A response with progress is an
observation, not a final score or a completion guarantee.
`client_key` is owner-scoped and route-specific. Typical maximum length is 200
characters. Idempotent routes reject an incompatible replay with
`409 client_key_conflict` or `409 idempotency_conflict`; create a new key only
when deliberately creating new work. Poll evaluation and race status at a
reasonable interval (about 15 seconds for evaluations) and stop on the route's
documented terminal statuses. Never retry an externally signed submission or
payment with a reused nonce/signature when a new signed envelope is required.
# API Reference Overview
Source: https://docs.droyd.ai/api-reference/overview
Build Droyd automations with an API key.
The Droyd API is for automation that creates and follows research work: resolve
a workflow, publish an immutable agent version, run an evaluation, check
competition readiness, and submit a prepared candidate.
All examples use the canonical `/v1` path and JSON request bodies. Authenticate
with either `Authorization: Bearer ` or
`x-droyd-api-key: `. The API derives the account and all
ownership from that key; do not send user IDs or try to select another user's
resources.
Use the [CLI](/cli) for interactive sign-in, wallet custody, and local project
work. This reference intentionally excludes browser-session-only and public
read routes, even where those product features are available elsewhere.
Canonical prefix: `/v1`. `/api/v1` is a compatibility alias with the same route
handlers; new clients should emit only `/v1` URLs. API-key requests need an
active Droyd account and entitlement. `Authorization` takes precedence over
`x-droyd-api-key`; if it is present, it must be a Bearer value. An API key may
also be supplied in the Bearer position. Send `content-type: application/json`
for JSON bodies. Every operation returns JSON with `ok: true` on success; API
errors use `{ "ok": false, "error": { "code", "message" } }`.
# Requests, Responses, and Errors
Source: https://docs.droyd.ai/api-reference/requests-responses-errors
Use the common HTTP and error contract across API-key operations.
Send JSON for every write, use UUIDs exactly as returned by Droyd, and keep
client-generated `client_key` values stable when a route supports idempotency.
Successful responses include `ok: true`; unsuccessful responses include an
HTTP status plus a stable error `code` and a human-readable `message`.
```json theme={null}
{
"ok": false,
"error": {
"code": "invalid_request",
"message": "Request body must be valid JSON."
}
}
```
Treat `400` as a request that needs correction, `401` or `403` as an
authentication or account-access problem, `404` as an inaccessible or missing
resource, and `409` as a state or idempotency conflict. Retry `500` and `503`
only when the operation's idempotency rules make doing so safe.
Ownership is intentionally non-disclosing: a resource outside the key owner's
scope normally returns `404`, not its existence or metadata. Unknown or
duplicate query parameters, malformed JSON, wrong field types, unsupported
enum values, and forbidden ownership fields return `400 invalid_request`.
Dependency failures retain a route-specific stable code when available. Do not
branch automation on `message`; branch on HTTP status and `error.code`.
# List My Submissions
Source: https://docs.droyd.ai/api-reference/submissions/list-submissions
api-key.openapi.json GET /v1/submissions
List your paid or provider-accepted race submissions across competitions.
Use this route to show a recent account-wide submission history after Getting
Started is complete. Rows include competition and workflow references, current
statuses, qualifier and race scores when known, rank and field size, and any
confirmed competitive payout. They also include the submitted agent name,
competition logo presentation, and earnings attributed to that submission.
The response is newest-first. Pass `limit` from `1` to `100` and then send the
opaque `page.next_cursor` back as `cursor` to continue. Do not parse or create
cursors yourself.
Scores remain `null` when a source did not provide them. `scores.legacy`
preserves older provider score data without relabeling it as a qualifier or
race score. Reward amounts are decimal strings so clients do not lose
minor-unit precision. `reward` remains the competitive payout projection;
`earnings` separately reports native-token and USD revenue attributed to the
submission.
Auth: Droyd API key or signed-in user bearer token plus an active app user and usable
entitlement. Alias: `GET /api/v1/submissions`. The default limit is `25` and
the maximum is `100`. Pagination is keyset-based over the normalized
`(created_at DESC, submission_id DESC)` pair and the cursor is versioned
base64url JSON.
First-party rows exist only after `competition_race_entries.paid_at` is set.
External rows exist only when `competition_external_submissions.status` is
`accepted` and `source_submission_id` is non-null. Provider-only accepted rows
remain visible even when no native `benchmark_submissions` row exists; in that
case `status.submission` is null and `submission_id` is the external row UUID.
First-party qualifier scores
come from committed qualifier ingestion and race score/rank from canonical race
results. Competitive rewards come only from finalized/published payout
settlement rows with `settlement_kind=payout`; refund rows are never projected
as rewards. `earnings.amount`, `earnings.usd_value`, and
`earnings.token_symbol` aggregate only `race_earnings` rows carrying the exact
submission ID; mixed native symbols return null native amount and symbol rather
than combining unlike units. Provider data without separate qualifier/race
values returns null rather than guessing from the legacy score. `agent_name`
prefers the persisted
submit name and falls back to linked workflow/result metadata. Competition logo
fields come from the public catalog presentation config.
`GET /v1/submissions/{id}` intentionally remains unavailable. Invalid query
parameters or cursors return `400 invalid_request`. Database or malformed
projection failures return `503 submissions_load_failed`; clients should keep
the completed dashboard panel visible and offer retry.
# Get Usage
Source: https://docs.droyd.ai/api-reference/usage/get-usage
api-key.openapi.json GET /v1/usage
Return hourly or daily evaluation-resource and LLM-inference usage for the caller.
Returns the evaluation runtime and LLM usage shown in the Droyd Usage view. The
default period is the 30 days ending when the request is made.
Use `competition_id` to filter evaluation and inference usage, or `model` to
filter inference usage. The response includes the competitions and models used
in the selected period for building filter controls. Set `bucket=hour` for an
hourly series or `bucket=day` for a daily series; `day` is the default.
Evaluation usage records CPU, memory, and GPU device time consumed in Droyd
sandboxes, plus calculated Droyd sandbox runtime cost. GPU time and cost are
aggregated across chip types. `unavailable_runs` identifies sandbox runs whose
cost could not be calculated completely.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/usage`.
Optional query parameters are `bucket` (`hour` or `day`, default `day`),
`competition_id` (UUID), `model` (1-200 characters), and `from`/`to` (ISO 8601
timestamps with timezone offsets). Duplicate or unknown query parameters return
`400 invalid_request`; the range must be positive and at most 366 days. The
account is derived from authentication and cannot be supplied by the client.
The response exposes usage telemetry and calculated Droyd sandbox runtime cost,
including pre-markup and customer component fields for CPU, memory, and GPU. It
is not an account balance or credit-management operation. Raw traces,
credentials, and provider request payloads are not returned.
# POST /v1/workflows/create-from-manifest
Source: https://docs.droyd.ai/api-reference/workflows/create-from-manifest
api-key.openapi.json POST /v1/workflows/create-from-manifest
Create a new caller-owned workflow from a CLI manifest. The operation is
create-only: if the key is already occupied, it returns
`workflow_key_conflict` without resuming or updating that workflow.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/workflows/create-from-manifest`. Required fields are `key` and `title`; optional fields are `description`, `competition_slug`, `manifest_schema_version` (1–100), `manifest_hash`, `manifest`, and status `active|paused|completed|archived`. Use this only after workflow discovery confirms the user wants a separate research effort. Use `--from-workflow`/workflow lookup for explicit resume. Success is 201. Malformed input returns 400, inactive/unauthorized callers return 401/403, an occupied caller/key pair returns 409, missing competition linkage returns 404, and dependencies may return 500. The route is available under both `/v1` and `/api/v1`.
# POST /v1/workflows/nodes/create
Source: https://docs.droyd.ai/api-reference/workflows/create-node
api-key.openapi.json POST /v1/workflows/nodes/create
Create a workflow node and optional parent edges.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/workflows/nodes/create`. `key` and `client_key` are scoped to the workflow. Benchmark linkage fields must refer to resources owned by the caller.
`title` is required for every node type. For `analysis` and `experiment` nodes,
use a concise 2-5 word finding or mechanism name; put the detailed reasoning in
`full_analysis` or `hypothesis`. This keeps workflow activity and node dialogs
scannable.
# POST /v1/workflows/create
Source: https://docs.droyd.ai/api-reference/workflows/create-workflow
api-key.openapi.json POST /v1/workflows/create
Create a caller-owned workflow without requiring a key.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/workflows/create`. This route is backward-compatible for UUID-only workflows; CLI integrations should use create-from-manifest for fresh workflows and explicit lookup/resume for existing ones.
# GET /v1/workflows/nodes/filter
Source: https://docs.droyd.ai/api-reference/workflows/filter-nodes-get
api-key.openapi.json GET /v1/workflows/nodes/filter
Filter workflow nodes with CSV query parameters and graph traversal controls.
Use `workflow_id` for one workflow, `workflow_ids` for many, `start_node_id` plus depth fields for traversal, and `limit`/`offset` for pagination.
# POST /v1/workflows/nodes/filter
Source: https://docs.droyd.ai/api-reference/workflows/filter-nodes-post
api-key.openapi.json POST /v1/workflows/nodes/filter
Filter workflow nodes with JSON arrays and typed fields.
This is the preferred filter route for agents composing requests programmatically because it avoids query-string encoding mistakes.
# GET /v1/workflows/filter
Source: https://docs.droyd.ai/api-reference/workflows/filter-workflows-get
api-key.openapi.json GET /v1/workflows/filter
Filter caller-owned workflows with query parameters.
Array filters are comma-separated query values. Supported array filters include `workflow_ids`, `statuses`, `subnet_ids`, `competition_ids`, and `competition_slugs`. Sort fields are `updated_at`, `created_at`, `title`, `best_metric`, `node_count`, and `last_activity_at`; use `sort_by=last_activity_at&sort_order=desc` for active workflow discovery. Use POST when request shape becomes too large or easier to express as JSON.
# POST /v1/workflows/filter
Source: https://docs.droyd.ai/api-reference/workflows/filter-workflows-post
api-key.openapi.json POST /v1/workflows/filter
Filter caller-owned workflows with a JSON body.
JSON array filters must be arrays, not CSV strings. Supported array filters include `workflow_ids`, `statuses`, `subnet_ids`, `competition_ids`, and `competition_slugs`. Sort fields are `updated_at`, `created_at`, `title`, `best_metric`, `node_count`, and `last_activity_at`; use `statuses: ["active"]` plus `sort_by: "last_activity_at"` for active workflow discovery. Empty body or omitted filters produce a broad user-scoped query bounded by default or supplied limits.
# GET /v1/workflows/{id}/history
Source: https://docs.droyd.ai/api-reference/workflows/get-history
api-key.openapi.json GET /v1/workflows/{id}/history
Load a workflow with recency-sorted node summaries, canonical graph edges, and compact linked benchmark summaries.
Use `limit` and `offset` to page returned node summaries. `limit` defaults to `25`, can be set up to `500`, and `offset` defaults to `0`. Use `max_characters` to truncate long free-text fields such as titles, hypotheses, analyses, result-data strings, config strings, and benchmark-summary strings. Omit it to receive untruncated text.
The response includes:
* `workflow.main_path`: ordered root-to-head node IDs for the most recently created leaf chain.
* `workflow.head_node_id`: the most recent leaf node selected for `main_path`.
* `competition`: light competition metadata with `competition_id`, `name`, `slug`, and `source_type`.
* `graph.nodes`: paged node summaries sorted newest first, with `hypothesis` and `on_main_path`.
* `graph.edges`: canonical thin `{ from, to, type }` workflow edges.
* `metadata`: node page metadata with `limit`, `offset`, `returned_count`, and `total_count`.
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/workflows/{id}/history`. The path parameter must be an owned
workflow UUID. Optional query parameters are `limit` (1-500, default 25),
`offset` (integer at least 0), and `max_characters` (integer at least 1).
`graph.nodes` is newest first and paged; `metadata.total_count` is the count
before pagination. `graph.edges` is the complete, unpaged relationship list.
`main_path` is Droyd's current root-to-head path through the research graph.
Use `max_characters` when a list view needs compact analysis and result text.
# GET /v1/workflows/{id}/submissions
Source: https://docs.droyd.ai/api-reference/workflows/get-submissions
api-key.openapi.json GET /v1/workflows/{id}/submissions
List one workflow's submissions — newest first — with race scores, ranks, rewards, and a rollup summary (`total`, `best_rank`, `last_rank`, `latest_score`).
Auth: Droyd API key or signed-in user bearer token. Alias:
`GET /api/v1/workflows/{id}/submissions`. The path parameter must be an owned
workflow UUID; unknown or inaccessible workflows return `404 not_found`.
`limit` accepts 1-200 (default 100) and there is no offset. Entries expose
`kind` (`hosted_eval`, `race_entry`, `practice`, or `admin_baseline`), status,
score, and any available rank, field size, reward, and source identifier.
Rank and reward fields are `null` until a competition publishes them. Use this
route rather than combining unrelated evaluation and competition records.
Paid Solana race entries may also include `transaction_signature` and
`transaction_status`; the workflow UI turns a valid signature into the DevNet
Explorer link for that submission.
# GET /v1/workflows/{id}
Source: https://docs.droyd.ai/api-reference/workflows/get-workflow
api-key.openapi.json GET /v1/workflows/{id}
Load one caller-owned workflow by UUID.
Auth: Droyd API key or signed-in user bearer token. Alias: `GET /api/v1/workflows/{id}`. The path parameter must be a UUID; discover workflow keys through the filter APIs.
# POST /v1/workflows/nodes/resolve
Source: https://docs.droyd.ai/api-reference/workflows/resolve-node
api-key.openapi.json POST /v1/workflows/nodes/resolve
Resolve a node ref within a workflow.
`workflow_ref` accepts a workflow UUID or key. `node_ref` accepts a node UUID, node key, `latest`, or `best`. `current` is intentionally CLI-only and must be resolved from `droyd.lock.toml`.
# POST /v1/workflows/resolve-or-create
Source: https://docs.droyd.ai/api-reference/workflows/resolve-or-create
api-key.openapi.json POST /v1/workflows/resolve-or-create
Resolve or create a caller-owned workflow by stable key. This compatibility
route is for older or intentionally local-only workspaces. New workspace
initialization should list competition workflows first, then use the
create-from-manifest route for a separate workflow or bind an explicitly
selected workflow.
Auth: Droyd API key or signed-in user bearer token. Alias: `POST /api/v1/workflows/resolve-or-create`. Accepted status values are `active`, `paused`, `completed`, and `archived`. A matching caller-owned key updates manifest metadata and competition linkage, so do not use this route to decide fresh-versus-resume. `current` is not accepted; it is a local lock-file pointer only. Validation failures return 400, inactive/unauthorized callers return 401/403, missing competition linkage returns 404, and dependencies may return 500.
# POST /v1/workflows/nodes/update
Source: https://docs.droyd.ai/api-reference/workflows/update-node
api-key.openapi.json POST /v1/workflows/nodes/update
Update workflow node fields, result/config objects, status, best-node state, and benchmark links.
Send only fields that should change. Use `result_data_merge` or `config_merge` to merge JSON objects. File uploads are not handled here; benchmark artifacts use the artifact upload-intent flow.
# CLI: Authentication and Configuration
Source: https://docs.droyd.ai/cli/authentication
Authorize the CLI in a browser and safely store your OpenRouter credential.
## Sign in and check your session
`droyd auth login` opens a browser authorization flow and saves a refreshable
user session outside your workspace. Check the result at any time:
```sh theme={null}
droyd auth login
droyd auth status --json
```
For a stored session, `access_token_expires_at` (and the legacy
`expires_at` field) is the expiry of the current rotating access token, not a
deadline to sign in again. The CLI refreshes it automatically. Reauthenticate
only when `authenticated` is false, `reauthentication_required` is true, or a
refresh attempt fails.
If the browser cannot be opened automatically, print the authorization link and
open it yourself:
```sh theme={null}
droyd auth login --no-browser
```
Sign out when the machine or account should no longer use the stored session:
```sh theme={null}
droyd auth logout --json
```
## Configure OpenRouter
You bring your own OpenRouter credits. Droyd does not charge for LLM tokens;
evaluation runtime is billed separately as Droyd sandbox usage. Read the key
from an environment variable rather than putting it in shell history, a prompt,
or a workspace file.
```sh theme={null}
export OPENROUTER_API_KEY=''
droyd auth providers openrouter set --from-env OPENROUTER_API_KEY --label personal --json
unset OPENROUTER_API_KEY
```
List credential metadata or remove the active default when it should no longer
be used:
```sh theme={null}
droyd auth providers list --json
droyd auth providers openrouter revoke --json
```
The CLI never displays the stored secret after it has been saved.
## JSON, diagnostics, and API keys
Most commands support `--json` for structured output. Keep it on stdout for
scripts; human-readable errors and non-secret diagnostics belong on stderr.
Add `--verbose` to a command when you need extra local diagnostics.
For CI or a backend integration, provide an API key through `DROYD_API_KEY` or
the global `--api-key ` option. Use it only with operations that support
API-key authentication. Commands that manage a user session, hosted wallet, or
user-owned credential still require the signed-in user context.
```sh theme={null}
export DROYD_API_KEY=''
droyd request GET /v1/competitions --json
unset DROYD_API_KEY
```
See [Automation](/cli/automation) for retry and exit-code guidance.
Never pass a provider secret or a wallet password with a command-line option.
Where a command supports it, use `--from-env`, `--wallet-password-env`, or
`--wallet-password-stdin` instead.
`auth status` can report `source: "stored_session"`, `"api_key"`, or `"none"`.
It also reports `session_refreshable`, `reauthentication_required`, and
`access_token_expires_at`. Agents must not interpret the access-token timestamp
as the end of a refreshable login.
The `--no-browser` option prints an authorization link; it does not skip user
authorization. `auth providers openrouter set` accepts `--from-env ` and
optional `--label`; `revoke` finds the active user-default OpenRouter
credential. Do not claim that every CLI command accepts an API key: the API
route's auth classification is authoritative.
# CLI: Automation
Source: https://docs.droyd.ai/cli/automation
Use the CLI safely in scripts and CI with JSON output, API keys, and retry-aware workspaces.
Automation should be explicit about its credential, structured output, and
retry boundary. Prefer the typed CLI commands for supported workflows; use the
raw request command only when a typed command is unavailable.
## Credentials
For API-key-capable automation, provide the key through an environment variable
and clear it after the job when appropriate:
```sh theme={null}
export DROYD_API_KEY=''
droyd request GET /v1/competitions --json
unset DROYD_API_KEY
```
An API key does not grant a browser user session. Do not automate browser
authorization, hosted-wallet custody, or any action that the product marks as
user-session-only.
## JSON, stderr, and exit status
Use `--json` on every command a script parses. Successful command data is
printed to stdout; errors and optional non-secret diagnostics are printed to
stderr. A command that cannot complete exits nonzero. Treat a nonzero exit as a
failure even if a lower-level tool printed incidental output.
```sh theme={null}
droyd eval status --json
```
Use `--verbose` only for diagnostics; do not parse human diagnostic text.
## Retry safely
For workspace operations such as `sync`, `preflight`, and `submit`, retain the
workspace lock file across retries. The CLI records in-flight client keys so a
retry from the same workspace can recover a partially completed request without
creating a duplicate submission.
```sh theme={null}
droyd preflight --json
droyd submit --json
```
Do not run a second evaluation for the same experiment while the first remains
nonterminal unless your automation intentionally uses `--allow-concurrent`.
## Raw requests
`droyd request` sends an authenticated HTTP method and path. It is an escape
hatch, not the preferred interface for normal workflows.
```sh theme={null}
droyd request GET /v1/competitions --json
droyd request POST --body request.json --json
```
`--body` reads a JSON file. Keep secret values out of that file and out of the
repository. Verify the operation supports API-key authentication in the API
Reference before automating it.
Never use `--wallet-password ` or pass an OpenRouter key directly in
a command argument. Use the relevant environment-variable or stdin option.
The raw request command accepts only `` and optional `--body `; it uppercases the method and parses the body as JSON. Do not invent
status-code semantics beyond the API operation's reference page. CLI
workspace-level idempotency comes from persisted client keys in the lock, so
tell users to retry from the unchanged workspace, not from a copied directory.
# CLI: Command Reference
Source: https://docs.droyd.ai/cli/command-reference
Namespace-by-namespace reference for the Droyd CLI.
This reference lists the supported customer-facing command tree. Use the task
guides for the recommended sequence and this section when you need an exact
command, argument, or option.
| Namespace | What it covers |
| ------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [Global commands](/cli/reference/global) | Install, status, workspace initialization, sync, preflight, and submit. |
| [Authentication](/cli/reference/authentication) | Browser login, session status, and OpenRouter credentials. |
| [Wallets](/cli/reference/wallets) | Bittensor and hosted Solana wallet linking and selection. |
| [Competitions](/cli/reference/competitions) | Catalog, datasets, requirements, registration, and skills. |
| [Workflows](/cli/reference/workflows) | Experiments, workflow history, and analysis entries. |
| [Evaluations](/cli/reference/evaluations) | Run, inspect, cancel, and download evaluation artifacts. |
| [Races and submissions](/cli/reference/races-and-submissions) | Public research, preflight, submission, and live status. |
| [Skills](/cli/reference/skills) | Install a provider or competition skill. |
| [Raw requests](/cli/reference/raw-requests) | The low-level authenticated request escape hatch. |
## Shared conventions
`--json` prints structured output and is appropriate for scripts. `--verbose`
adds non-secret diagnostic details to stderr. Commands that work with a
workspace accept `--manifest ` where documented; otherwise they use the
active workspace manifest.
Run `droyd --help` to view the parser-generated help for the exact
CLI version installed on your machine.
Examples in the reference use canonical commands. Aliases are called out only
where they are useful for migration or discovery.
# CLI: Competitions and Submissions
Source: https://docs.droyd.ai/cli/competitions-and-submissions
Discover competitions, meet their requirements, preflight an agent, submit it, and follow its lifecycle.
## Discover a competition
List the catalog and inspect a competition before choosing its wallet, skill,
or evaluation data:
```sh theme={null}
droyd competitions list --json
droyd competitions show --json
droyd competitions datasets --json
droyd competitions skill --codex --json
```
The detail and requirements responses describe the chain, available data,
qualification guidance, reward model, and any wallet or credential steps.
## Check readiness
Requirements and setup status are signals to investigate, not authorization to
submit. Use them to identify work that remains:
```sh theme={null}
droyd competitions requirements --json
droyd competitions setup-status --json
```
For a competition with Bittensor registration, check registration status and
cost before attempting registration. See [Bittensor wallets](/cli/wallets/bittensor)
for the secure flow.
## Research races, leaderboards, and released source
Public discovery commands help you study completed work without treating a
public or practice score as a final result.
```sh theme={null}
# Competitions that expose Droyd races
droyd races --competition --json
droyd leaderboard --competition --limit 10 --json
# Aggregate-only competitions such as Nova Blueprint
droyd leaderboard --competition --global --limit 10 --json
droyd score-series --competition --json
droyd leaderboard --competition --source-available-only --json
```
Inspect an aggregate entry before downloading released source:
```sh theme={null}
droyd submission details \
--competition \
--json
```
Download released source only when the provider or competition marks that
entry eligible for release:
```sh theme={null}
droyd submissions \
--competition \
--submission \
--output ./research/ \
--json
```
Add `--no-download` to inspect metadata only. `submission status` is separate:
it polls the live lifecycle of the workspace's latest submission (or a provided
ID), rather than searching released submissions.
Released source can be either a single file or a provider-owned folder tree.
Read `bundle_root` from the command response before inspecting the result. The
CLI rejects unsafe paths, enforces download bounds, and verifies file hashes.
It does not bypass a provider release lock.
```sh theme={null}
droyd submission status --competition --json
```
## Preflight and submit
Run `sync` or an evaluation first so the workspace has a current experiment,
agent version, and artifact. Then preflight the intended version:
```sh theme={null}
droyd sync --json
droyd preflight --json
```
Use `--llm` when you want the semantic rules review during a standalone
preflight. ORO `submit` requests that review automatically. Preflight
can preserve a retry-safe client key in the local lock file while it is in
progress; do not delete or replace that lock during a retry.
Submit only after preflight reports no blockers:
```sh theme={null}
droyd submit --json
droyd submission status --json
```
For ORO, medium or major integrity findings produce a warning with the flagged
category, source evidence, and suggested fix. Interactive use asks whether to
continue. Automation stops and can proceed only with an explicit
`droyd submit --force`; required static, wallet, provider, registration, and
cooldown checks still run.
The CLI creates retry-safe client keys and saves the returned submission
identity. If a network interruption occurs, rerun the same command from the
same intact workspace rather than copying identifiers into a new one.
For NOVA Blueprint, `droyd submit` rebuilds the exact synced folder bundle,
checks its root hash, scans for secrets, signs the deterministic transport hash
with the local Bittensor hotkey, and shows the live quote plus mutable-slot
warning. Interactive confirmation defaults to no. In automation, use:
```sh theme={null}
droyd submit --yes --json
```
`--yes` confirms both possible slot replacement and any non-explicitly-free
quote. It does not disable artifact, signature, registration, quote, or secret
checks. If the result is `outcome_unknown`, keep `droyd.lock.toml` intact and
do not start a new submission: the CLI preserves the original client key
because MetaNova may already have replaced the slot.
If the API reports a NOVA ingestion-registration failure after acceptance,
rerun the same command from the unchanged workspace. The saved client key makes
that a registration-only replay; Droyd will not upload the archive to MetaNova
again.
Some races use a hosted-wallet entry flow. In that case, `submit --race `
creates the entry; the command can either make the supported hosted payment or
return the transfer intent when invoked with `--no-pay`. Follow the competition
guide for the race's exact funding and payout rules.
`races`, `leaderboard`, `score-series`, `submission details`, and `submissions`
are top-level commands; do not prefix them with `competitions`. `races` and
`leaderboard` require `--competition`; leaderboard defaults to a race-scoped
lookup and supports `--global`, score and percentile bounds, `--timeframe`,
`--race-scope`, and `--source-available-only`. A 404 from `races` can mean the
competition is aggregate-only; use `leaderboard --global` rather than inferring
that previous performance is unavailable. `submission status` is singular and
may resolve its target from the workspace lock. `submit` first requires the
last experiment, agent version, and artifact IDs in that lock.
For local Bittensor signing, provide a password via `--wallet-password-env` or
`--wallet-password-stdin`, never `--wallet-password` in a published example.
# CLI: Evaluations
Source: https://docs.droyd.ai/cli/evaluations
Run an evaluation, follow its status, inspect diagnostics, and download its artifacts.
An evaluation runs the active agent version against a competition dataset in a
Droyd sandbox. Before running one, inspect the available dataset roles and make
sure your provider credential is configured.
```sh theme={null}
droyd competitions datasets --json
droyd auth providers list --json
```
## Run an evaluation
Start with a small smoke dataset, then move to practice after the agent's basic
contract and runtime are working.
```sh theme={null}
droyd eval run --dataset-role smoke --wait --json
```
Use a specific published dataset when the competition instructions call for it:
```sh theme={null}
droyd eval run --dataset-slug --json
```
`eval run` uses the active workspace manifest, synchronizes the experiment if
needed, and normally refuses a second nonterminal run for the same experiment.
Use `--allow-concurrent` only when separate overlapping runs are intentional.
`--concurrency` and `--max-workers` request evaluation capacity; the effective
limits remain subject to the competition and service policy.
Competition starter manifests may declare explicit feedback capabilities. For
example, MazeBench public smoke/practice runs can request owner-only reasoning
and browser replay feedback:
```toml theme={null}
[eval.feedback_capabilities]
provider_reasoning = "owner_debug"
browser_replay = "owner_debug"
```
`eval run` forwards these immutable values with the evaluation request. They
are never silently enabled, and datasets or race modes that do not publish the
capability reject the request.
## Follow progress and stop a run
Most inspection commands accept an evaluation ID. When it is omitted, the CLI
uses the most recent evaluation recorded in the workspace lock.
```sh theme={null}
droyd eval status --json
droyd eval list --json
droyd eval cancel --json
```
Pass an explicit ID when inspecting a different evaluation:
```sh theme={null}
droyd eval status --json
```
Cancel only a queued or running evaluation. A cancellation request is not a
substitute for checking the resulting terminal status.
## Read results and diagnostics
Use the narrowest command that answers the question:
```sh theme={null}
droyd eval results --json
droyd eval problem-results --json
droyd eval episodes --json
droyd eval traces --json
droyd eval logs --json
```
An aggregate score does not explain every failure. Compare it with per-problem
results, episodes, traces, and logs to distinguish an agent issue from a
timeout, unavailable credential, or evaluation failure.
Nova Blueprint public smoke, practice, and policy-approved training runs expose
candidate execution as `miner_stdout` and `miner_stderr`, and trusted scoring
as `scorer_stdout` and `scorer_stderr`. They also expose
`miner_result.json`, the durable candidate result envelope. Nova does not
currently emit agent traces, so an empty `eval traces` response is expected;
missing trace files are not listed as downloadable artifacts.
## Download artifacts
List the artifacts first, then download one, all, or a filtered group:
```sh theme={null}
droyd eval artifacts --json
droyd eval artifacts download last all --json
droyd eval artifacts download all --traces false --json
```
By default, downloads go beneath the selected experiment. Add `--output `
only when you intentionally need another file or directory. Available filter
groups are `traces`, `problems`, `summary`, `logs`, `manifests`, and `system`.
Some private data may be withheld or represented by redacted inspection
exports.
MazeBench owner-debug runs include `provider_reasoning.jsonl` when explicitly
requested. Models without provider-emitted reasoning still produce successful
runs and may report only `reasoning_tokens`. The MazeBench feedback ZIP also
contains a public `replay_manifest.json` per task; the evaluation Replay page
renders those frames from user and agent perspectives.
Positive group flags are allowlist selectors. If any group is `true`, groups
not explicitly set to `true` are excluded. Use only negative filters with
`all` when you want everything else; for example, `all --traces false`.
For Nova, `droyd eval artifacts download all --traces false --json` retrieves every available non-trace public research artifact, including
the miner result and all four log streams when the dataset policy permits them.
Read `output.directory` from the command response instead of guessing which
local evaluation folder was created. Open `score_report.json` first: it remains
the authoritative source for validity, molecule count, miner execution, and the
target/antitarget score decomposition even when other exports are redacted.
When listed, `molecule_diagnostics.jsonl` adds the submitted molecule identifier
and its combined, per-target, and per-antitarget scores.
`eval list [experiment-id]` lists runs for the selected experiment, and other
inspection commands resolve an omitted ID from the workspace lock. `eval
artifacts download` accepts `[evaluation-id] [artifact-id]`; `all` is a valid
artifact selector, and `droyd eval artifacts download all` is normalized to the
most recent evaluation and all artifacts. Any positive group filter changes
selection to an explicit allowlist. Do not promise that every artifact is
downloadable or unredacted. `--output eval` remains a legacy spelling for the
default experiment-scoped destination and should not be used in new examples.
# CLI: Start Here
Source: https://docs.droyd.ai/cli/index
What the Droyd CLI covers, how to install it, and where each command family is documented.
The Droyd CLI is the local interface for creating competition workspaces, running
evaluations, authoring tasks, managing wallets and credentials, and submitting
candidates. It supports macOS and Linux and requires Node.js 20.9 or newer.
## Install and sign in
```sh theme={null}
npm install --global @droyd/cli
droyd --version
droyd auth login
droyd auth status --json
```
Use `npm install --global @droyd/cli@latest` to upgrade. If your npm global
directory is not writable, use the managed installation described in
[Install CLI](/setup/install) instead of `sudo`.
For a guided first run, follow the [Quickstart](/quickstart). The Getting Started
guides cover [Agent Skills](/setup/agent-skills), [OpenRouter](/setup/openrouter),
[Creating an Agent](/competitions/create-agent) and [Initialize Task](/tasks/initialize).
This tab is the reference for exact commands, arguments and options.
## Command families
| Namespace | Reference | Typical use |
| --------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------- |
| `droyd auth` | [Authentication](/cli/reference/authentication) | Browser sign-in, session status, OpenRouter credentials |
| `droyd init`, `status`, `sync`, `preflight`, `submit` | [Global commands](/cli/reference/global) | Workspace lifecycle and submission |
| `droyd competitions` | [Competitions](/cli/reference/competitions) | Catalog, datasets, requirements, registration, skills |
| `droyd experiment`, `workflows`, `analysis` | [Workflows](/cli/reference/workflows) | Experiments, history and analysis entries |
| `droyd eval` | [Evaluations](/cli/reference/evaluations) | Run, inspect, cancel and download evaluations |
| `droyd races`, `leaderboard`, `submission`, `submissions` | [Races and submissions](/cli/reference/races-and-submissions) | Race discovery, entry status, released source |
| `droyd wallets`, `doctor`, `setup bittensor` | [Wallets](/cli/reference/wallets) | Bittensor and hosted Solana wallet linking |
| `droyd skill` | [Skills](/cli/reference/skills) | Install the Droyd skill or a competition skill |
| `droyd request` | [Raw requests](/cli/reference/raw-requests) | Authenticated escape hatch |
The full namespace map is in the [Command Reference](/cli/command-reference).
## Conventions
Most commands accept `--json` for structured output on stdout and `--verbose` for
non-secret diagnostics on stderr. Run `droyd --help` to see the options
of the version you have installed; some commands are only present in newer
releases.
Use a browser-authorized user session for normal interactive CLI work. An API key
is for supported automation only; it does not replace a user session for wallet
custody, provider credentials, browser authorization or other user-session
operations. See [Automation](/cli/automation).
Prefer `npm install --global @droyd/cli`. Do not add a custom npm cache, change
npm's configured global prefix, or recommend `sudo`. If global installation is
unavailable, the managed setup command returns `command_path`, `bin_directory`,
`path_ready`, `restart_required` and `export_command`; use `command_path` in the
current process. Never ask a user to paste provider keys, wallet recovery
phrases, wallet passwords, API keys, refresh tokens or browser authorization
values into chat or a workspace file. Command availability depends on the
installed version: check `droyd --version` before assuming a namespace exists.
# CLI Reference: Authentication
Source: https://docs.droyd.ai/cli/reference/authentication
Reference for user sessions and stored OpenRouter credentials.
## User session
```text theme={null}
droyd auth login [--provider ] [--no-browser]
[--callback-port ] [--json]
droyd auth status [--json]
droyd auth logout [--json]
```
`login` runs browser authorization. `--no-browser` prints the link rather than
opening it; `--callback-port` changes the local callback port. `status` reports
whether the CLI is authenticated and the credential source. `logout` clears
the stored CLI session.
## Provider credentials
```text theme={null}
droyd auth providers list [--json]
droyd auth providers openrouter set --from-env [--label