FARPY Public API V1

FARPY Render API quickstart

Check service health, inspect current capabilities and pricing, upload a supported render file, submit the render, then download its result, receipt and proof.

1. Create an API key

Sign in, open Account Settings, and create an API key. The secret is shown once, so store it securely and never place it in browser code or public logs.

export FARPY_API_KEY="YOUR_FARPY_API_KEY"

Discover current service facts first

Call the public health endpoint before sending an API key or uploading a supported render file. If it does not return HTTP 200, stop and retry later.

curl -fsS https://farpy.com/v1/health

After health succeeds, inspect current renderer capabilities, public pricing, request limits, and the OpenAPI contract.

Production flow

health
capabilities
pricing
upload
submit
status
download
receipt
proof

API properties

Python client

Download the dependency-free Python 3 client and run the complete workflow with one high-level method.

import os
from farpy_client import FarpyClient, FarpyError

client = FarpyClient(os.environ["FARPY_API_KEY"])

capabilities = client.capabilities()
pricing = client.pricing()
limits = client.limits()

print(capabilities)
print(pricing)
print(limits)

try:
    result = client.render(
        "scene.blend",
        output_path="render.zip",
        poll_interval=2.0,
        overall_timeout=3600.0,
    )
    print(result["job_id"])
    print(result["receipt"])
    print(result["proof"])
except FarpyError as exc:
    print(exc.code)
    print(exc.retryable)
    print(exc.suggested_action)
    print(exc.request_id)
    raise

Download farpy_client.py · Open the Python example · Verify SHA-256 checksums

Start here

set -euo pipefail

BASE="https://farpy.com/v1"
FILE="\${1:-scene.blend}"

: "\${FARPY_API_KEY:?Export FARPY_API_KEY first}"

command -v curl >/dev/null
command -v jq >/dev/null
command -v sha256sum >/dev/null
test -f "$FILE"

case "$FILE" in
  *.blend) ;;
  *) echo "ERROR: input must be a .blend file" >&2; exit 2 ;;
esac

AUTH="Authorization: Bearer $FARPY_API_KEY"
FILE_SHA256="$(sha256sum "$FILE" | awk '{print $1}')"
UPLOAD_KEY="upload-$FILE_SHA256"
SUBMIT_KEY="submit-$FILE_SHA256"

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

echo "1/8 UPLOAD"
curl -fsS "$BASE/renders" \
  -H "$AUTH" \
  -H "Idempotency-Key: $UPLOAD_KEY" \
  -F "file=@$FILE" \
  -o "$TMP/upload.json"

jq . "$TMP/upload.json"

JOB_ID="$(jq -er '
  .job_id //
  .render.job_id //
  .render.id //
  .id //
  empty
' "$TMP/upload.json")"

echo "JOB_ID=$JOB_ID"

echo
echo "2/8 PRICE"
curl -fsS "$BASE/pricing" \
  -H "$AUTH" \
  -o "$TMP/pricing.json"

jq . "$TMP/pricing.json"

echo
echo "3/8 PREFLIGHT"
jq -n \
  --arg filename "$(basename "$FILE")" \
  '{
    filename: $filename,
    renderer: "blender",
    frame_start: 1,
    frame_end: 1,
    frame_count: 1
  }' > "$TMP/preflight-request.json"

curl -fsS "$BASE/renders/preflight" \
  -H "Content-Type: application/json" \
  --data-binary @"$TMP/preflight-request.json" \
  -o "$TMP/preflight.json"

jq . "$TMP/preflight.json"

echo
echo "4/8 SUBMIT"
curl -fsS -X POST "$BASE/renders/$JOB_ID/submit" \
  -H "$AUTH" \
  -H "Idempotency-Key: $SUBMIT_KEY" \
  -o "$TMP/submit.json"

jq . "$TMP/submit.json"

echo
echo "5/8 STATUS"
while :; do
  curl -fsS "$BASE/renders/$JOB_ID" \
    -H "$AUTH" \
    -o "$TMP/status.json"

  jq . "$TMP/status.json"

  STATE="$(jq -r '
    .status //
    .state //
    .render.status //
    .render.state //
    empty
  ' "$TMP/status.json" | tr "[:lower:]" "[:upper:]")"

  case "$STATE" in
    DONE|COMPLETED|COMPLETE|SUCCEEDED|SUCCESS)
      break
      ;;
    FAILED|ERROR|CANCELLED|CANCELED)
      echo "ERROR: terminal state $STATE" >&2
      exit 3
      ;;
  esac

  sleep 5
done

echo
echo "6/8 RECEIPT"
curl -fsS "$BASE/renders/$JOB_ID/receipt" \
  -H "$AUTH" \
  -o "$TMP/receipt-response.json"

jq . "$TMP/receipt-response.json"

RECEIPT_URL="$(jq -er '
  .receipt_url //
  .receipt.url //
  .render.receipt_url //
  empty
' "$TMP/receipt-response.json")"

curl -fsSL "$RECEIPT_URL" -o "$TMP/receipt.json"
jq . "$TMP/receipt.json"

echo
echo "7/8 DOWNLOAD"
curl -fsS "$BASE/renders/$JOB_ID/download" \
  -H "$AUTH" \
  -o "$TMP/download-response.json"

jq . "$TMP/download-response.json"

DOWNLOAD_URL="$(jq -er '
  .download_url //
  .output_url //
  .artifact_url //
  .download.url //
  .artifact.url //
  .render.download_url //
  .render.output_url //
  empty
' "$TMP/download-response.json")"

OUTPUT="$PWD/$JOB_ID.output"
curl -fsSL "$DOWNLOAD_URL" -o "$OUTPUT"

echo "OUTPUT=$OUTPUT"

echo
echo "8/8 SHA256 VERIFY"
EXPECTED_SHA256="$(jq -er '
  .output_sha256 //
  .artifact_sha256 //
  .sha256 //
  .output.sha256 //
  .artifact.sha256 //
  .artifacts[0].sha256 //
  empty
' "$TMP/receipt.json")"

ACTUAL_SHA256="$(sha256sum "$OUTPUT" | awk '{print $1}')"

echo "EXPECTED_SHA256=$EXPECTED_SHA256"
echo "ACTUAL_SHA256=$ACTUAL_SHA256"

test "$ACTUAL_SHA256" = "$EXPECTED_SHA256"

echo
echo "VERIFY_OK=true"
echo "JOB_ID=$JOB_ID"
echo "RECEIPT_URL=$RECEIPT_URL"
echo "DOWNLOAD_URL=$DOWNLOAD_URL"

API overview · Agent integration guide · Error and retry guide · Webhook delivery guide · Quickstart · OpenAPI · Pricing · Status · Proof