Convilyn Forge API (0.1.0)

Download OpenAPI specification:

Builder forge — mints a platform-unique, deterministically generated treasure creature bound to a user-authored workflow.

Lifecycle

  1. User finishes configuring a workflow in the Builder.
  2. Frontend calls POST /forge/commit { workflow_id }.
  3. Server verifies ownership, debits 1U, generates a GeneVector from the workflow_id, and persists it atomically.
  4. Response carries the resulting Treasure (gene vector + hash + id).

Idempotency

A re-call with the same workflow_id returns the existing treasure and does not charge again (already_bound: true).

Errors

  • 402 Insufficient forge credits — caller is out of U. Frontend triggers inline Paddle top-up; no redirect to /billing.
  • 404 Workflow not found — includes the case of a workflow the caller does not own (leak-resistant).
  • 422 Invalid workflow_id — malformed id (not uw_[a-f0-9]{24}).
  • 503 Gene-space exhausted — mint could not find a unique gene after the bounded re-roll budget. Retry later.

Related docs

  • frontend-web/src/lib/treasure/genes.ts — canonical GeneVector.
  • backend-api/app/services/treasure_genes.py — Python mirror.
  • backend-api/app/services/forge_billing.py — 1U billing seam (Worktree C enriches the body).

Forge

Treasure minting + per-forge billing. Covers the 1U commit debit + the pre-flight balance quote consumed by the builder.

Forge a treasure creature bound to a workflow

Mints a deterministic treasure for the given workflow. Idempotent on workflow_id — double-calls return the same treasure and are never double-charged.

Authorizations:
BearerAuth
Request Body schema: application/json
required
workflowId
required
string^uw_[a-f0-9]{24}$

Responses

Request samples

Content type
application/json
{
  • "workflowId": "uw_0123456789abcdef01234567"
}

Response samples

Content type
application/json
{
  • "treasureId": "string",
  • "workflowId": "string",
  • "geneHash": "string",
  • "geneVector": {
    },
  • "mintedAt": "2019-08-24T14:15:22Z",
  • "boundAt": "2019-08-24T14:15:22Z",
  • "alreadyBound": true
}