A Node.js Client for Skavio Agent Tools: Deadlines, Idempotency and the Timeout That Proves Nothing
An asynchronous processing API breaks the assumption most HTTP clients are quietly built on — that a failed request and a failed job are the same event. Skavio Agent Tools accepts a submission and returns work to you later, with a shared prepaid credit wallet behind it. When a socket closes early, the honest client records an unknown outcome and waits on a bound it chose in advance, rather than resubmitting and hoping.
A timeout answers one question and raises three
Skavio Agent Tools is a company-scoped, authenticated API for document, invoice, audio and data processing, with self-service keys, asynchronous jobs and a shared prepaid credit wallet. The supplied Processing API capability record — verify the current Agent Tools documentation for the exact contract — describes quote-first submissions, atomic credit reservations, one settlement for a successful job, and release of the reservation on permanent failure. That design is useful for cost control and awkward for naive clients, because a client-side timeout tells you only that a response did not arrive in time. It does not tell you whether the job was accepted, whether credits were reserved, or whether processing will still complete. Treat those as separate questions and the client design follows: persist intent before the first byte leaves the process, and resolve uncertainty by looking up documented state rather than by starting over.
- A client timeout is a local observation about a network exchange, not a server verdict about a job.
- Quote, reservation and settlement are distinct states; only the service's own documented record resolves them.
- Log the logical submission before the first attempt so an unrecorded outcome remains reconstructable.
Two budgets: the request deadline and the job wait
Most integrations fail here by using one number for two different jobs. The first budget is the per-request deadline: how long a single HTTP exchange — an upload, a status read, a result download — may take before your client gives up on that exchange. The second is the overall wait budget: how long the application will keep a logical job open before it escalates to a human or reconciliation step. Both are application policies chosen by your team. Neither is a Skavio service limit, and presenting them in code or documentation as platform behaviour misleads the next maintainer. Size them by operation: a multi-file upload deserves more headroom than a status read. Keep polling polite too. The supplied Processing API limits list 120 requests per minute; a tight poll loop spends your own rate budget on questions you already know the answer to. Interval and backoff curves are your design decisions; the current Agent Tools documentation is the authority on what the service actually enforces.
- Name the two budgets separately in configuration and in logs, or the first incident will conflate them.
- Apply a longer deadline to uploads and downloads than to status checks.
- Do not describe your own polling interval or backoff curve as a Skavio limit or promise.
Retry the idempotent operation, never the deterministic failure
A safe Node.js client has one rule that carries most of the weight: a single stable idempotency key per logical submission, generated before the first attempt, persisted, and reused on every retry of that submission. Regenerating the key on retry is how one document becomes two jobs and two reservations. The second half of the rule is classification. Deterministic client errors — a rejected key, an invalid payload — will fail identically on the tenth attempt, so retrying them only multiplies log noise. Retry only operations that the current documentation identifies as safe or idempotent, and check the documentation for the field name, lifetime and deduplication behaviour of the key rather than assuming them. Support for a specific transient-error signal, or for a retry-after hint, is not something to guess at either: verify it before building a strategy on it.
- Generate the idempotency key once per logical submission and store it with the request fingerprint.
- Reuse that key on every retry; never mint a fresh one to "try again cleanly".
- Skip retries for authentication and validation failures, which are deterministic by nature.
Completion is verified, not assumed
Sooner or later a job finishes while nobody is watching. Two mechanisms can bring that news back, and both need the same skepticism you applied to the timeout. Completion webhooks must have their signature verified on the receiving server before the payload is trusted as a business event; an unverified POST is an unauthenticated claim. Authenticated result downloads mean the download path carries the same access requirements as the rest of the API, so API keys stay server-side and never enter browser code or a shared repository. Keep a local job ledger — logical submission, idempotency key, job identifier, quoted price, current state, timestamps — so that when the wait budget expires you mark the submission as unknown and reconcile it against the service's documented record instead of resubmitting. Job-state names, endpoint paths, the authentication header format and the webhook signature scheme must come from the published documentation, not from memory.
- Verify webhook signatures before any completion event changes your local state.
- Download results through authenticated requests; never ship a company key to a client.
- When the wait budget expires, record an unknown outcome and reconcile — do not resubmit.
A pre-flight checklist before the first real file
The cheapest time to discover a design problem is with documents nobody cares about. Build the first client against fictional invoices or sample media, and confirm the whole path — submission, quoted price, state transitions, completion, authenticated download — before a single customer file enters the pipeline. Scope the API key to what the integration actually does, and keep it out of client bundles, logs and support tickets. The supplied Processing API limits also shape retention habits: an upload envelope of 100 files and 500 MB, up to 100 queued company jobs, four active jobs, and seven-day result retention mean the API is a processing service, not an archive. Download and store finished artifacts in your own system on a schedule you control, because a job that expires is not a job you still have. Finally, keep scope discipline in what you claim: this is the production Agent Tools API, not a staging Invoice, Reporting or Research agent, and nothing in a processing integration implies approved production accounting posting.
- Run the first end-to-end test on fictional documents and verify every state transition.
- Issue least-privilege, company-scoped keys and keep them server-side only.
- Download finished results promptly instead of treating the service as long-term storage.
- Verify and plan around the supplied Processing API limits — request rate, upload envelope, queued and active jobs, retention — in the current documentation.