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 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.
- Browser sessionHomepage inspect → start uses a signed-in cookie. Not machine-to-machine.
- Account API keyAccount Settings
farpy_…Bearer keys for Public API V1 (/v1/renders). Shown once. - Job API agent key
farpy_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
- Inspect —
POST /node/v1/uploads/inspect — NO SPEND - Quote —
read quote_id, frames, price_cents, qualified_1c, pricing_version - Start —
POST /node/v1/uploads/{id}/start — SPEND BOUNDARY - Status —
GET /node/v1/jobs/{job_id} or signed webhook - Download —
ZIP via download_url - Receipt —
receipt + SHA-256 (file identity, not art review)
Inspect and quote do not spend. Start reserves wallet funds. Server cents are authoritative.
Live service contract
GET /v1/health— service healthGET /v1/capabilities— workload availabilityGET /v1/pricing— current pricingGET /v1/limits— current limitsGET /v1/openapi.json— OpenAPI 3.1
Guides
- API quickstart — inspect, quote, start, then download.
- Agent rendering — machine-operated inspect → start, polling, webhooks.
- Blender Render API — programmatic Blender Cycles upload-to-download.
- Octane lane — pilot / limited. Quoted per job.
- Video lane — limited encode/transcode/process. Quoted per job.
- Webhook delivery — signed terminal events and duplicates.
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.
#!/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.