APIs and automation
Safe retries in a file API: avoid duplicates
A practical guide to retrying outbound calls to Apification Cloud without duplicating folders, files, transformations, or shared links.
The problem: a timeout does not tell you whether the operation happened
The dangerous case in a file integration is not a clear error, but the response that never arrives. Your backend calls an API to create a folder, upload a file, launch a transformation, or prepare a shared download; the connection is cut off by a timeout; and the client does not know whether the server executed the action. If you simply retry, you may create two folders, register two copies of the same file, queue two transformations, or publish two equivalent links.
The first operational decision is to separate reads from writes. In HTTP, methods such as GET, HEAD, and OPTIONS are considered safe because the client is not requesting a state change. By contrast, actions that create, modify, move, delete, or queue work must be treated as writes. RFC 9110 defines an idempotent request as one whose intended effect when repeating several identical requests is the same as executing it once; for that reason, after a communication failure, automatic retries are advisable only when the operation is designed to support them.
- Reads: querying lists, details, the status of a job, or results that have already been generated.
- Writes: creating folders, uploading files, updating metadata, moving items, sending items to the trash, queuing transformations, or creating shared access.
- Gray area: when you did not receive a response, assume neither success nor failure; store the attempt and confirm by querying.
Which file operations need protection
In Apification Cloud, server-to-server REST API integration makes it possible to manage Cloud resources, users, configuration, and transformation jobs from the backend of an integrating product. Cloud is described as an organized, versioned space for managing files, services, and digital projects ready to share. Some operations are naturally query-based; others change the state of the workspace where files, services, and digital projects live.
Transformations also require care. Apification makes it possible to process documents, images, video, audio, and data through a guided assistant, and its integration makes it possible to manage transformation jobs from the backend. Creating or submitting a transformation job is an asynchronous write: your application may lose the response and not know whether the job was registered. If you retry without local state or a stable logical identity, you may end up paying the operational cost of two equivalent processes or mixing results from different versions of the file.
- Protect every action that changes state as a candidate for controlled retrying.
- Do not retry costly transformations without checking whether a job already exists for the logical attempt.
- Treat moving an item as an organizational change, not an identity change: in Cloud, its properties and access rules remain associated with the same item.
Recommended model: external identity, local state, and confirmation
The most reliable pattern starts in your own application. Before calling Apification, create a local operation record with a stable external identifier from the source system, the action type, the logical content version, and an initial state. That record does not replace the API; it helps your backend remember what it tried to do, with which payload, and what it expects to find afterward. In multi-tenant integrations, this table prevents two customers, projects, or versions from accidentally sharing the same deduplication.
After an uncertain call, do not decide based only on the HTTP client error code. If the operation was a read, you can retry normally. If it was a write, first query whatever you can: item details, job status, version history, or previous local records. Apification Cloud makes it possible to review item history, download previous versions, and restore content; this helps reconstruct which content ended up active when there was a race between retries, updates, or moves.
- Minimum states: pending, sent, accepted, confirmed, failed, requires review.
- Minimum fields: tenant, source object, logical version, action, normalized payload, local operation key, resulting Cloud resource, and local timestamp.
- Practical rule: do not delete the local record when the network fails; it is precisely the evidence you will need to decide the next step.
Design an idempotency key that does not depend on the name
Although HTTP defines what it means for a request to be idempotent, each specific API must be checked against its own contract. In Apification, the integration page indicates that the downloadable OpenAPI document contains the request and response schemas; use it to validate how each call is built and what data it returns. Also keep a local operation key in your database so you can recognize when two retries belong to the same logical attempt.
The key should not simply be the file name or a timestamp generated on every attempt. The name changes, repeats across users, and usually contains presentation decisions, not business identity. A good design combines tenant, source object identifier, action type, and logical version. For example, a conceptual key could be derived from tenant A + contract 583 + transform to optimized PDF + version 7. If the user uploads a new version, the key must change; if the same attempt is only repeated because of a timeout, it must be preserved.
- Include: tenant or source account, business resource, exact action, logical version, and, if applicable, transformation operation.
- Avoid: per-attempt timestamps, random UUIDs per retry, visible file names as the only identity, and keys shared across different actions.
- Verify: same local key, same payload, same functional intent, and OpenAPI contract consulted before automating retries.
Step-by-step flow to transform and publish a file
A robust transformation flow starts before the request is sent. First validate in your system which business file will be processed and which logical version it represents. Then register or manage the file in Cloud using the corresponding API according to the OpenAPI contract. Store the returned reference alongside your local operation. If the response is lost, mark the attempt as uncertain and seek confirmation before sending another copy.
To transform, consult the operation contract when you need to, prepare a request compatible with the documented schemas, and create the transformation job through the server-to-server integration. When you receive an acceptance or job reference, store it; then query the API according to the contract to review its progress and results. Only when the result is confirmed should you publish the download or generate the appropriate sharing step.
- Prepare: resolve tenant, source object, version, and destination folder.
- Send: use a stable local key for the write and store the normalized payload.
- Confirm: query the job until you have status and results, without creating another job out of impatience.
- Publish: share the transformed item or download only after associating the correct result with the correct version.
When to retry, query, or stop the flow
Retry automatically when the operation is a read or when the request is idempotent in the sense of RFC 9110. If the write depends on API-specific rules, do not assume undocumented guarantees: consult the OpenAPI, keep the same payload for the same logical attempt, and record what the client decided and why. Retry safety comes from the combination of HTTP semantics, the API contract, and local state.
Query before repeating when the error occurred after bytes were sent, when the timeout arrived late, or when your client does not know whether the connection was cut before or after Apification received the request. Stop the flow for human review when you detect a different payload with the same intent, more than one candidate resource, mixed versions, or results incompatible with the local state. In those cases, retrying may increase the damage: it is better to present an internal panel with the operation, tenant, possible Cloud resources, transformation job, and recommended action.
- Retry: status GET requests and operations designed as idempotent.
- Query: timeout after sending, lost response, job with no local reference but possible remote acceptance.
- Stop: inconsistent keys, visible duplicates, changed source version, transformation already completed for another version.
Common mistakes and how Apification fits in
The most common failures are not sophisticated: using timestamps as unique names, generating a new key on every retry, mixing the original file with a later version, retrying asynchronous transformations because the user refreshed the screen, or treating a received webhook as confirmation of a previous write. A webhook is a later event that must be processed with its own deduplication; it does not replace confirmation of the outbound call made by your backend. Separate both circuits: API client to Apification on one side, webhook receiver on the other.
Apification fits into this design because it offers server-to-server REST API integration, an OpenAPI document with request and response schemas, organized and versioned Cloud, guided file transformation, sharing through links, users, or groups, and signed webhooks with retries, history, and statistics. The practical recommendation is to generate the client from the OpenAPI contract or validate it against that contract, store intermediate states in your database, and use Cloud and transformation queries to confirm results before moving forward.
- Do not confuse receiving events with confirming writes initiated by your backend.
- Do not use the visible file name as a functional identifier.
- Do not publish a transformed download until you know which logical version produced the result.
- Do not promise the product team no duplicates just because you have retries; design states, keys, queries, and review.
Frequently asked questions
Can I retry any failed call to a file API?
No. Reads are usually candidates for retrying, but writes must be protected. Retry automatically only when the operation is designed as idempotent or when the API contract and your local state allow you to do so without duplicating effects.
What should a local operation key contain?
It should link tenant, business resource, exact action, and logical version. The key must be preserved across retries of the same attempt and change when the functional intent or content version changes.
Does a webhook confirm that my previous write succeeded?
Not necessarily. A webhook is a later event and must be processed in a separate flow. To confirm an outbound write, query the resource, job status, or available results through the corresponding API.
How do I avoid duplicating file transformations?
Store the operation locally, use a stable key to identify the logical attempt, keep the reference returned by the API, and query the status or result according to the OpenAPI contract before creating another attempt.
Sources and further reading
Documentation consulted while preparing this article.
- HTTP Semantics (RFC 9110) — RFC Editor / IETF
- Safe (HTTP Methods) — MDN Web Docs
- Integra Apification en tu producto — Apification
- Cloud de Apification — Apification
Explore Apification
Related articles
APIs and automation
JSON and XML for integrations: how to prepare files that APIs can consume without breaking the flow
A practical guide to normalizing JSON and XML before transforming, sharing, or sending them to an API without causing avoidable errors.
APIs and automation
Integrate embedded Cloud without exposing credentials
A practical guide to embedding Apification Cloud with an iframe, REST API, and mediator backend while keeping credentials, permissions, and sensitive actions out of the browser.
APIs and automation
How to receive webhooks without duplicating actions in file workflows
A practical guide to designing idempotent webhook receivers: validate signatures, log events, respond quickly and process files without duplicating effects.