FARPY API

Inspect a file. Read the quote. Then start.

Same path as the browser: inspect the input, read the exact quote, then start. Live public API and MCP follow the Blender .blend contract. Start is the spend boundary. Download the ZIP and receipt after completion.

Quickstart

Create API key · Download client · OpenAPI

Quickstart

Create a Job API farpy_agent_ key. Download farpy_client.py. Prepare does not spend. Start does.

export FARPY_AGENT_KEY="farpy_agent_..."

python3 farpy_client.py prepare scene.blend
python3 farpy_client.py start UPLOAD_ID \
  --quote-id QTE-... \
  --legal-acceptance FARPY_LEGAL_V1

python3 farpy_client.py status JOB_ID

Authentication

Three auth systems. They are not interchangeable.

  1. Browser sessionHomepage inspect → start uses a signed-in cookie. Not machine-to-machine.
  2. Account API keyAccount Settings farpy_… Bearer keys for Public API V1 (/v1/renders). Shown once.
  3. Job API agent keyfarpy_agent_… Bearer keys for inspect/quote/start. Different store from Account Settings. Convergence is later work.

Job API: Authorization: Bearer farpy_agent_<secret>

Public API V1: Authorization: Bearer farpy_<secret>

Revoked keys stop authenticating without delay.

Inspect

POST /node/v1/uploads/inspect — NO SPEND. Returns upload_id and a locked quote. Do not hard-code renderer availability, pricing, limits, or cancellation behavior.

Quote

Read quote_id, frame range, frame_count, price_cents, qualified_1c, and pricing_version before start. Client cents are not authority. The server locked quote is the price.

Start

POST /node/v1/uploads/{id}/start — SPEND BOUNDARY. Send that quote_id and legal_acceptance: "FARPY_LEGAL_V1". Do not send price_cents.

NO SPEND: prepare() / inspect() / quote()

SPEND BOUNDARY: start(..., quote_id=..., legal_acceptance="FARPY_LEGAL_V1")

DEPRECATED: FarpyClient.render() — upload+submit, no quote gate

Status

GET /node/v1/jobs/{job_id} or a signed webhook. Poll until the job is terminal. Do not retry a terminal failed or cancelled job.

Download

Completed work exposes a ZIP via download_url. The job is not complete until the ZIP, receipt, and proof are retrievable.

Receipt

Receipt plus SHA-256 of the ZIP bytes. Matching hash means matching file identity, not an art review.

Order of calls

  1. InspectPOST /node/v1/uploads/inspect — NO SPEND
  2. Quoteread quote_id, frames, price_cents, qualified_1c, pricing_version
  3. StartPOST /node/v1/uploads/{id}/start — SPEND BOUNDARY
  4. StatusGET /node/v1/jobs/{job_id} or signed webhook
  5. DownloadZIP via download_url
  6. Receiptreceipt + SHA-256 (file identity, not art review)

Inspect and quote do not spend. Start reserves wallet funds. Server cents are authoritative.

Live service contract

Guides

Model Context Protocol (MCP)

MCP V1 is live at https://api.farpy.com/mcp. Same contract as the browser: inspect → quote → start. Start is the only spend tool. Discord bot is also available. MCP for agents.

Tools: farpy_inspect, farpy_quote, farpy_start, farpy_status, farpy_download, farpy_receipt. Auth stays in the environment, never as a tool argument. Bearer farpy_agent_ keys only. Do not call farpy_render or farpy_submit_render.

Copy-paste inspect then start

The key stays in the environment. Wallet is reserved only on start.

bashprepare-then-start.sh
#!/usr/bin/env bash
set -euo pipefail

: "${FARPY_AGENT_KEY:?Set FARPY_AGENT_KEY (Job API farpy_agent_ key). Account Settings farpy_ keys are a different store.}"
: "${1:?Usage: ./prepare-then-start.sh scene.blend}"

ORIGIN="https://farpy.com"
FILE="$1"
AUTH="Authorization: Bearer $FARPY_AGENT_KEY"

# NO SPEND: inspect returns upload_id + locked quote.
INSPECT="$(
  curl -fsS "$ORIGIN/node/v1/uploads/inspect" \
    -H "$AUTH" \
    -F "file=@$FILE"
)"
echo "$INSPECT" | jq '{upload_id, quote_id, frame_start, frame_end, frame_count, price_cents, qualified_1c, pricing_version, quote}'

UPLOAD_ID="$(printf "%s" "$INSPECT" | jq -er '.upload_id')"
QUOTE_ID="$(printf "%s" "$INSPECT" | jq -er '.quote_id // .quote.quote_id')"
PRICE_CENTS="$(printf "%s" "$INSPECT" | jq -er '.price_cents // .quote.price_cents')"
echo "QUOTE $QUOTE_ID = $PRICE_CENTS cents. Decide before start. Wallet is not reserved yet."

# SPEND / reservation boundary. Do not send price_cents.
curl -fsS -X POST "$ORIGIN/node/v1/uploads/$UPLOAD_ID/start" \
  -H "$AUTH" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg quote_id "$QUOTE_ID" '{quote_id:$quote_id, legal_acceptance:"FARPY_LEGAL_V1"}')"

Public API V1 routes (still live)

Paths relative to https://api.farpy.com/v1. Prefer inspect/start above. These can reserve on upload.

GET/healthCheck service availability before sending credentials or work.
GET/capabilitiesRead currently accepted renderers, formats, queue state, and availability.
GET/pricingRead the active machine-readable pricing contract.
GET/limitsRead upload, frame, rate, and workload constraints.
GET/openapi.jsonDownload the OpenAPI 3.1 contract.
POST/rendersLegacy Public API V1 upload. Can reserve before a locked-quote accept. Prefer inspect.
POST/renders/preflightPlanning check. Not a locked quote.
POST/renders/{job_id}/submitLegacy start after /renders upload.
GET/renders/{job_id}Public API V1 job state.
POST/renders/{job_id}/cancelCancel before worker claim when the live contract permits it.
GET/renders/{job_id}/downloadRetrieve completed artifact delivery information.
GET/renders/{job_id}/receiptRetrieve the economic completion receipt.
GET/renders/{job_id}/proofRetrieve execution evidence and artifact hashes.

System status · Receipt guide · Manage API keys