Playbooks API primer for agents

Give a coding agent the minimum complete contract for creating, polling, and consuming a Playbooks job safely.

Use this page with the canonical OpenAPI document. OpenAPI is authoritative for exact schemas; this primer is authoritative for the integration sequence and operational decisions.

Contract at a glance#

  • Base URL: BLACKPEARL_API_BASE_URL, configured for the deployment.
  • Authentication: Authorization: Bearer $BLACKPEARL_API_KEY on every /v1 request.
  • Create: POST /v1/playbooks using operation create_playbook_v1_playbooks_post and schema PlaybookInput.
  • Poll: GET /v1/jobs/{job_id} using operation get_job_v1_jobs__job_id__get.
  • Create response: 202 Accepted with schema PublicPlaybookJobResponse.
  • Create retry safety: send Idempotency-Key; matching retries replay the original response for 24 hours.
  • Result: when the job succeeds, result is schema PublicPlaybookResult.
  • Retention: expires_at is 30 days after creation; store results needed after that time.
  • Errors: schema ErrorResponse; branch on error.code, not HTTP status alone.

Create separate projects and keys for development, staging, and production. Hosted development calls still perform real work and record real usage.

Minimal request#

Set the configured API URL and a server-side project key:

export BLACKPEARL_API_BASE_URL="https://api.blackpearl.com"
export BLACKPEARL_API_KEY="replace-with-your-project-key"
export BLACKPEARL_IDEMPOTENCY_KEY="playbook-$(date +%s)-$$"

curl --fail-with-body --silent --show-error \
  --request POST "$BLACKPEARL_API_BASE_URL/v1/playbooks" \
  --header "Authorization: Bearer $BLACKPEARL_API_KEY" \
  --header "Idempotency-Key: $BLACKPEARL_IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{"target_company_domain":"acme.example"}'

Provide at least one of target_company or target_company_domain. A domain is a hostname without a scheme or path. Optional tone values are consultative, direct, and technical; model is currently default. Omit sections for the complete result.

Persist the idempotency key before the first request and the returned id immediately after success. If the connection is lost or a server response is ambiguous, repeat the exact POST with the same key within 24 hours. A matching request returns the original response without creating or billing another job. A changed request returns idempotency_key_reused; idempotency_in_progress means retry the same request and key after a short delay.

Poll every terminal state#

Wait 2 seconds before the first GET, then use exponential backoff with jitter capped at 10 seconds. Apply a caller deadline and retain the job ID so polling can resume later. A client timeout does not cancel server work.

StatusTerminalAction
queuedNoWait and poll again.
runningNoOptionally show progress, then poll again.
succeededYesValidate and consume the typed result.
failedYesStop and surface the job error.
canceledYesStop; there is no public cancel operation.

On success, useful first outputs are result.business_summary and the first item in result.sales_angles. Collections are arrays. Research-derived scalar fields can be null; follow PublicPlaybookResult rather than inventing fallback fields.

Errors, retries, and usage#

  • rate_limit_exceeded is transient. Wait at least the Retry-After value, then retry with bounded backoff and jitter.
  • quota_exceeded and budget_exceeded also use status 429, but require a reset or configuration change. Do not automatically retry them.
  • Authentication, entitlement, and validation codes require the caller to change credentials, project state, access, or input.
  • A safe GET may be retried for a documented transient 5xx. Repeat an ambiguous create POST only with its original idempotency key and exact input.
  • Polling is rate-limited but does not start another billed Playbooks generation. Inspect the completed job's usage and reconcile project totals through GET /v1/usage.
  • A job or candidate read after expires_at returns 410 job_expired. Create a new job if no client-stored result exists.

Do not assume#

  • Do not assume a key prefix creates a sandbox.
  • Do not assume a fixed completion-time SLA, fixed request-per-minute limit, or cancellation endpoint.
  • Do not assume an idempotency key remains replayable after 24 hours or can be reused with different input.
  • Do not wait only for succeeded; all three terminal states stop polling.
  • Do not treat every 429 or 5xx as retryable.
  • Do not expose a project key in browser or mobile code.

For complete examples, use the Quickstart. For field interpretation and recovery details, use Playbooks, Jobs and resumable polling, Errors and retry decisions, and Limits, budgets, and usage.