Trinsfer Developer Guide
Everything you need to integrate Trinsfer into your stack. The API is REST + JSON,
authenticated with a Bearer API key, and respects standard HTTP semantics. All examples
below were tested against the live https://trinsfer.com/api/v1 base URL.
Introduction
The Trinsfer API gives you programmatic access to two products:
- Transfers — create file-transfer envelopes, query metadata, update title/recipient/expiration, soft-delete.
- Speed tests — submit and retrieve internet-speed test results from your own infrastructure.
All endpoints live under https://trinsfer.com/api/v1 and return JSON with a consistent envelope:
Quickstart (60 seconds)
Create an account
Free signup, no card required. OAuth (Google / Discord / Telegram / X / Kick) also works.
2Generate a key
Profile → API keys → "+ New API key". Copy the secret — it is shown only once.
3Make your first call
GET /api/v1/account returns your plan, limits and current usage.
Build something
Create transfers, manage speed tests or wire into your CI/CD.
Fire your first request right away:
Authentication
Every request must include the header Authorization: Bearer <your-key>. Keys look like tk_a1b2c3d4_… — the first 11 characters (tk_xxxxxxxx) are the prefix and identify the key. The full secret is stored only as SHA-256 on our side; we never see it again after creation.
Listing and rotating keys
From /profile#api-keys you can:
- Generate new keys with custom scopes.
- Regenerate a key — old secret stops working immediately, you receive the new one once.
- Revoke or permanently delete a key.
Error handling
Every non-2xx response carries error.code and error.message. The cheat-sheet below maps codes to HTTP statuses and what you should do.
expires_days below your plan's max_expiry_days.Retry-After seconds and retry. Consider exponential backoff.pay_url (your /profile#api-keys).Rate limit & quota headers
Every response (including errors) carries headers that describe your remaining quota — no need to call /account for that:
X-RateLimit-Limit— requests per minute allowed by your plan.X-RateLimit-Remaining— how many you have left in the current minute.X-RateLimit-Reset— seconds until the counter resets.X-Quota-Limit-Month— free requests included this month.X-Quota-Used-Month— how many you have already used.X-Quota-Overage— request count above your free quota.X-Quota-Overage-USD— money owed at current pricing.X-Trinsfer-Plan— your plan:free,monthly,annual.
Scopes & permissions
Scopes restrict what a key can do — assign the minimum required:
transfers:read— list and read transfers + files.transfers:write— create, update, delete transfers.speed:read— list speed test history.speed:write— submit and delete speed test results.
Requesting an endpoint without the matching scope returns HTTP 403 insufficient_scope.
Transfer expiration limits
The expires_days field on POST /transfers and PATCH /transfers/<token> is capped by your plan. Exceeding it returns HTTP 422 expiry_too_long.
Pay-per-use billing
Each plan ships with a generous free monthly request quota. Past that, every request adds a tiny pay-per-use charge that you can settle on demand from /profile#api-keys.
- Overage is computed monthly and reset every 1st of the month.
- While you owe less than $20, the API keeps responding normally — you only see the bill grow.
- Above $20 unpaid, the API returns
HTTP 402 quota_payment_requiredwith apay_urlthat opens PayPal at the exact owed amount.
Account
Returns the current user, active plan, rate-limit ceiling, monthly quota and current overage. Useful as a health-check / ping endpoint for your SDK.
Transfers
List your transfers, newest first. Supports ?limit=<1-100> (default 20) and ?offset=<0+>.
Create a transfer envelope. Returns token + upload_url — the upload itself uses Trinsfer's own binary chunk protocol (POST /upload_chunk, see "Recipes" below). It is not TUS.
Retrieve a single transfer with its file list and signed per-file download URLs.
Updatable fields: title, recipient_email, message, expires_days (capped by your plan).
Soft-deletes the transfer. Files are purged after the grace period.
Speed tests
List your stored speed test history. Same pagination as transfers.
Recipe: upload a file with chunks
Trinsfer uses its own lightweight binary chunk-upload endpoint at POST /upload_chunk (clean URL — no .php). Each chunk is a raw binary POST; metadata travels in X-* headers. The full flow is three steps, all with friendly URLs: POST /init_transfer (or POST /api/v1/transfers) to get a token, then POST /upload_chunk for every chunk, then POST /finalize to flip the transfer to ready. The server assembles each file automatically once its last chunk arrives.
Protocol
- Create the transfer envelope with
POST /api/v1/transfers(API) orPOST /init_transfer(web) and keep the returnedtoken. - Pick a chunk size (5 MB is what the web app uses) and split each file.
- For each chunk,
POST /upload_chunkwith the raw bytes as the body and these headers:X-Token— the transfer token.X-File-Id— a stable identifier you generate per file (UUID).X-Chunk-Index— zero-based chunk number.X-Total-Chunks— how many chunks the file will be.X-File-Name— original file name.X-File-Size— total file size in bytes.Content-Type: application/octet-stream.
- Call
POST /finalizewith{ "token": "<token>" }once all files are uploaded — the transfer flips fromuploading→ready.
X-Chunk-Index to retry a failed upload, the server overwrites that chunk and recounts.Webhooks
Subscribe to events that happen on your account from /profile#webhooks. Every delivery includes:
X-Trinsfer-Event— event name.X-Trinsfer-Delivery— unique delivery id (for idempotency).X-Trinsfer-Signature—sha256=<hex>of the body using your webhook secret.
Events emitted
transfer.created— fires when a transfer is created via the API or web app.transfer.downloaded— fires every time someone downloads from a transfer link.transfer.expired— fires when a transfer crosses its expiration date.transfer.password_failed— fires on a wrong password attempt.speed_test.submitted— fires when a speed test is stored.api_key.used— fires when an API key is used to authenticate a request (throttled to at most once per 60s per key).
Verify a delivery (PHP)
Libraries
Until we ship official SDKs you can use any HTTP client. We've validated the API works with:
- JavaScript — native
fetch, axios, ky. - Python —
requests,httpx. - PHP — Guzzle, Symfony HttpClient, raw cURL.
- Go —
net/httpwithhttp.Header{Authorization: "Bearer …"}. - Postman — import any cURL above with "Import → Raw text".
Want to publish a community SDK? Open a PR or email dev@trinsfer.com.