Skip to content

Production Checklist

Before moving from a script to production, go through this checklist item by item. Each item links to the details.

  • API keys live only in server-side environment variables or a secrets manager, and never appear in frontend code, apps, code repositories, or logs. See Authentication.
  • Production and testing use different keys, and keys for short-lived purposes have an expiry date.
  • Your team knows what to do if a key leaks: roll it in the console and choose “Immediately”, or disable it. See Manage API Keys.
  • You have a key rotation process: when rolling a key, give the old key a grace period, and let it expire only after the new key is deployed.
  • You persist the task_id right after submitting, and record the submission time and parameters in your own system.
  • You poll about every 15 seconds, with a scheduled loop that checks unfinished tasks in batches instead of blocking per task. See Task Lifecycle.
  • A business timeout doesn’t mean failure: after a timeout you keep the task_id and can still fetch the result later.
  • You decide success or failure from status only, and never treat a non-empty error_code as failure.
  • When a submit request times out, disconnects, or returns -1, you check List Tasks first instead of blindly resubmitting. See Error Handling.
  • If you use wait_seconds, your HTTP client timeout is longer than wait_seconds, and you handle a non-final task coming back.
  • You decide whether a request succeeded from ret in the response body, not the HTTP status code — while also handling non-200 statuses and network errors.
  • You parse msg (a JSON string) into a displayable message, falling back to the raw text if parsing fails.
  • Request bodies contain only fields defined by the endpoint, in snake_case (task_id, wait_seconds).
  • Your response parsing ignores unknown fields, so new fields added later don’t break it.
  • -1, 1024, and 1025 are retried with backoff; 1001, 1003, 1022, 1023, 1029, 1030, and 1031 aren’t retried automatically but raise an alert or a message.
  • An unknown error_code is treated as “task failed, not charged”, and its error_message is logged.
  • Bulk submissions are throttled on the client to stay under the per-minute limit, with backoff on 1024 / 1025. See Rate Limits & Quotas.
  • The platform list is fetched from the API, not hardcoded, and platforms in maintenance are skipped.
  • You pick the tier by use case: P2 for batch and scheduled work, P1 for time-sensitive work. See Platforms, Priority & Country.
  • You get an alert when your balance drops below a threshold (the console Usage page shows balance and expiry), so tasks don’t stall on 1023. See Billing & Credits.
  • You check that raw_result exists before reading it, and fill in defaults for omitted zero-value fields.
  • elapsedMs is parsed from a string into a number.
  • cited is handled as three states, with a missing field not treated as false. See Working with Results.
  • When you use thinking mode, you check raw_result.thinking to see whether it was actually on, rather than trusting the thinking you submitted. See Thinking mode.
  • url is checked to be an http(s) link before use.
  • Images you need long-term are copied to your own storage (imageUrl expires).
  • Platform citation markers in the answer text are cleaned up as needed before showing it to users.
  • For each request you log the endpoint, ret, latency, task_id, and the ipalfish-trace-id response header (if present), to help with troubleshooting.
  • You monitor the task failure rate and the distribution of error_code values per platform; if a platform keeps returning crawl_failed, consider switching temporarily.
  • You regularly reconcile against the console Request Logs and Usage pages.