Twine does not keep your files. An uploaded file is removed shortly after it has been
delivered. The file transfer record — including the destination’s identifier for the document —
is kept indefinitely, so a transfer from months ago is still readable long after the file is
gone.
Uploading
Send the file base64 encoded, alongside where it should go:Where the file goes
A file travels through a file transfer domain mapping that has Twine on the source side and your destination system on the target side. If your organization has exactly one such mapping, it is used automatically and you can omitdomain_mapping_id. Otherwise, name the
one you want: list them with GET /v1/org/domain-mappings and pick the one whose from_domain is
file_transfer.
Naming a mapping that does not exist is rejected with a 422 rather than accepted and left
undelivered, so a mistyped id fails immediately instead of at poll time.
Twine does not check whether the destination can actually accept the file. If something is missing
or unsupported, the transfer fails during delivery and the reason appears on the job — see
Status below.
Employees
employee_id is the Twine employee UUID. Twine resolves it to that employee’s identifier in the
destination system itself, so you never need to know the remote id.
The field is optional, because not every document belongs to someone. Be aware that destinations
which file documents under an employee will reject one that has none — Hibob, for example, stores
documents per employee and nowhere else. Destinations addressed by path, such as SFTP and S3, take
files with no employee happily.
Retrying safely
Supply anidempotency_key of your own choosing, unique within your organization — something stable
per document, such as your own identifier for the certificate. Repeating a request with a key you
have used before always returns 200 and the original transfer’s id, never a duplicate record.
What happens next depends on how the first attempt ended:
So a retry after a network timeout is safe, and so is a retry after a delivery failure — you never
need a fresh key to get a failed document moving again. A retry re-sends the file you post with it
(Twine does not keep the original bytes), and the transfer record adopts that file’s name, size and
checksum.
Polling for the identifier
Delivery is asynchronous, so the identifier is not available on the response to the upload. Poll the transfer until it is:What the identifier looks like
Destination systems do not agree on how a document is addressed, so a transfer carries three fields and fills in whichever apply:remote_id— the destination’s own identifier for the document. This is what most HR systems return and what you will usually want.remote_path— where the file landed, for destinations addressed by path rather than by id (SFTP, S3). For these, the path is the identity; there is no id.remote_employee_id— the employee’s identifier in the destination. Some systems only address a document as the pair of this andremote_id.
delivered with
every remote field null, which means the file arrived but the destination gave nothing to
reference it by.
Status
Conditions
Uploads are subject to the same conditions as any other domain. Two are checked, and both must pass:- File transfer conditions are evaluated against the uploaded file itself — its
content_type,size,original_nameand so on. This is where a rule like “PDFs only” belongs. - Employee conditions are evaluated against the employee the file belongs to, when you supplied
an
employee_id. A file with no employee skips this check rather than failing it.
rejected, not failed — it was never sent, and nothing
went wrong. If an upload you expected to land keeps coming back rejected, check the conditions on
the destination’s system integration and on its file transfer domain mapping.
status is worked out from the delivery job each time you read the transfer rather than being
stored on it. That keeps it honest, but it also means you cannot filter a list by status. To find
transfers in a particular state, filter Jobs instead, or read status off
each transfer.
Listing
employee_id, system_integration_id, file_name, inserted_at and updated_at.
This lists transfers Twine performed. It is not a view of the documents that exist in a
connected system — Twine does not mirror the destination’s document library.
Your own reference data
The optionalmetadata object is returned unchanged on every read of the transfer, which is a
convenient place to keep the identifier your own system knows this document by. It takes a flat
object with string keys and string, number or boolean values, up to 2 KB encoded.
It is also readable from property mappings, which is how a value you
send with the upload can influence the delivery itself. Map metadata on the File transfer side and
pull a key out of it — filing a document in a folder your own system chooses per upload, rather than
one the integration fixes for every file, is the usual reason to. See
Hibob for a worked example.
Two keys are reserved and always describe the transfer itself, so sending them has no effect:
source (always public_api) and content_sha256 (the checksum Twine computed).