Build an agent in 10 minutes

By the end of this page, your agent will have created a Promethic prompt, run it, revised it, and saved a record. Same surface the desktop app uses; same surface every other agent uses. Every snippet is copy-pasteable.

What you'll need: a Promethic account (sign up free at app.getpromethic.com) and either curl, the Promethic CLI (one npm install), or any MCP-aware client (Claude Desktop, Cursor, ChatGPT Pro/Enterprise, Codex CLI).

2 minConcepts (just enough)

Promethic stores prompts. Each prompt has one or more versions (promptText + model settings). When you run a version, the server sends your input to the model and streams back the output. A run is a transient session; you finalize it to save a permanent record.

Records vs sessions — what auto-finalize does

By default, run_prompt auto-finalizes. The model returns its output; the server immediately saves a record; you get a recordId back. One call, one round trip, durable result. This is what most agents want.

If you want to revise the model's output before saving, pass autoFinalize: false on run_prompt. You get a runId; call revise_run to add turns, then finalize_run when the output is what you want. Records are the permanent training-data layer; sessions are scratch space.

Set the persistent default at the user level via the desktop / Expo Settings UI, or with promethic config set auto-finalize-mcp-runs <true|false> in the CLI. Per-call autoFinalize always overrides.

1 minStep 1: mint an API key

Sign in at app.getpromethic.com, open Settings → Developer Keys → "Mint a key", give it the scopes you want (read, execute, write), and copy the pmk_ string — you'll only see it once.

For this tutorial, mint a key with all three scopes (you can narrow it later with per-tool grants).

3 minStep 2: pick your surface, run the recipe

Three equivalent paths — pick whichever fits your stack:

Path A — curl (any environment)

Set the key once:

export PROMETHIC_KEY="pmk_your_key_here"
export API="https://api.getpromethic.com"

Create a prompt (use a real model id from /api/v2/models/config; gpt54nano_2c6f9b4d is cheap):

PROMPT_ID=$(curl -s -X POST "$API/api/v2/public/prompts" \
  -H "X-API-Key: $PROMETHIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Translate-to-haiku",
    "version": {
      "promptText": "Translate the following sentence into a 5-7-5 syllable English haiku. Return ONLY the haiku.\n\nSentence: {{input}}",
      "modelSettings": { "model_id": "gpt54nano_2c6f9b4d", "parameters": {} }
    }
  }' | jq -r '.id')

echo "Prompt: $PROMPT_ID"

Run it:

curl -s -N -X POST "$API/api/v2/public/prompts/$PROMPT_ID/run" \
  -H "X-API-Key: $PROMETHIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": "The morning fog softened the silhouettes of the cypress trees." }'

(autoFinalize is read from the URL query, not the body — ?autoFinalize=true is the default; pass ?autoFinalize=false to keep the run unfinalized for revisions, as in Step 3.)

You'll see SSE events. The final event is record_finalized with your recordId. Done.

Path B — Promethic CLI

npm install -g @soulwarestudio/promethic-cli
promethic auth login   # paste your pmk_ key
promethic prompts create \
  --name "Translate-to-haiku" \
  --prompt-text "Translate the following sentence into a 5-7-5 syllable English haiku. Return ONLY the haiku.\n\nSentence: {{input}}" \
  --model-id "gpt54nano_2c6f9b4d"
# capture the prompt id from the output, then:
promethic run <prompt-id> -i "The morning fog softened the silhouettes of the cypress trees."

Path C — Hosted MCP (Claude Desktop, Cursor, ChatGPT Pro+, Codex CLI)

Add the Promethic MCP server to your client. /agents has the client-specific config. Then in your agent chat:

"Create a Promethic prompt called 'Translate-to-haiku' that translates a sentence into a 5-7-5 syllable haiku. Use model gpt54nano. Then run it on this sentence: 'The morning fog softened the silhouettes of the cypress trees.'"

The agent calls promethic_create_prompt + promethic_run_prompt for you. Your output is back as both the agent's reply AND a saved record in your Promethic account.

2 minStep 3: revise (the part agents usually skip)

The auto-finalize default optimizes for one-shot runs. To iterate, run with autoFinalize: false first:

# curl
RUN_ID=$(curl -s -N -X POST "$API/api/v2/public/prompts/$PROMPT_ID/run?autoFinalize=false" \
  -H "X-API-Key: $PROMETHIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": "The morning fog softened the silhouettes of the cypress trees." }' \
  | grep -oE '"runId":"[^"]+' | head -1 | cut -d'"' -f4)

# Add a revision turn
curl -s -N -X POST "$API/api/v2/public/runs/$RUN_ID/revise" \
  -H "X-API-Key: $PROMETHIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "instruction": "Make it more melancholy." }'

# When you like the output, finalize
curl -s -X POST "$API/api/v2/public/runs/$RUN_ID/finalize" \
  -H "X-API-Key: $PROMETHIC_KEY" -d '{}'

Or in the CLI: promethic run <prompt-id> -i "..." --no-auto-finalizepromethic revise <run-id> -i "Make it more melancholy."promethic finalize <run-id>.

1 minStep 4: list records, the prompt's training data

Records aren't just "what the model output." Each one carries the input, the model output, any revision turns, and any user edits — the structured data that lets Promethic refine the prompt for you over time. You can list them anytime:

curl -s "$API/api/v2/public/records?promptId=$PROMPT_ID" \
  -H "X-API-Key: $PROMETHIC_KEY" | jq '.records[0:3]'

1 minStep 5: handling crash recovery (the boring-but-important part)

On rare failures (a server crash mid-call, a network drop), a retry of the same Idempotency-Key may return:

{
  "type": "https://api.getpromethic.com/errors/idempotency_outcome_unknown",
  "reasonCode": "idempotency_outcome_unknown",
  "status": 500,
  "detail": "The original request died mid-flight. The domain change MAY OR MAY NOT have landed. Verify via a GET before any retry..."
}

The fix is always: verify via GET first, then retry only if nothing landed. For each tool, a specific recipe lives in the recovery section of the agent docs. For example: if create_prompt failed mid-flight, list your prompts and check if one with your name already exists. If yes, the create succeeded; do not retry. If no, mint a new Idempotency-Key and retry.

Don't blindly retry with a new key on this error. If the original mutation already landed, the retry duplicates it. Always GET-verify state first.

Next steps