Add a file to a test case
const url = 'https://beta-api.plune.ai/v1/test-cases/example/files?name=example';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'image/png'}, body: 'binary'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url 'https://beta-api.plune.ai/v1/test-cases/example/files?name=example' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: image/png' \ --data binaryA file onto a test case of its own (the case page’s Files, #1234). The body IS the file, as for a result’s (POST /v1/results/{id}/files): a picture (PNG, JPEG, WebP) at most 2 MiB, or a text (application/json, text/plain) at most 512 KiB as UTF-8, cleaned of credentials before it is kept. Up to 30 files, 20 pictures and 10 texts of them in the database. The project’s files share one budget of 1 GiB: an upload that would pass it first deletes the project’s oldest files kept in the database — a person’s as much as a reporter’s — and its answer says what went (evicted). The list of the same files says beforehand what one more would cost (budget.evicts). Another file — a video, an archive — needs the project’s own bucket: …/files/uploads, then PUT, then POST /v1/files/{id}/complete. A reader of the project cannot add one; someone else’s case, run or bug is a 404, the same as an invented one. 600 requests a minute a person.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The test case.
Query Parameters
Section titled “Query Parameters ”What the file is called; only the last segment of a path is kept, cleaned of credentials.
Request Body required
Section titled “Request Body required ”Any JSON document, UTF-8.
object
Example
{ "currency": "EUR", "rate": 1.08}Text, UTF-8 — a log is one.
Example
POST /v1/cart/coupon 422 31msResponses
Section titled “ Responses ”Stored. evicted is there only when the budget sent files away for it
A person’s file just stored, and — only when it sent anything away — what the budget evicted for it.
object
The last segment of the name it was uploaded with, cleaned of credentials as a text is.
In the database (storage: db): image/png, image/jpeg, image/webp, application/json or text/plain — a log is text/plain. In the bucket (storage: bucket): the media type it was announced with, lower case and without parameters, any type.
Bytes as kept: in the database a picture at most 2 MiB and a text at most 512 KiB, counted after its credentials are cleaned, so it can differ from what was sent; in the bucket the size that was announced and found there.
db: Plune keeps the bytes, GET /v1/files/{id} returns them. bucket: they are in the project’s own bucket, and GET /v1/files/{id} answers 409 in_bucket (the way to read them is GET /v1/files/{id}/link).
The user who added it; null once that account is gone.
What the 1 GiB budget of the project sent away to make room (#1234): the project’s oldest files kept in the database, a person’s as much as a reporter’s.
object
Example
{ "id": "3f0c2a7e-1b5d-4c8e-9a61-2d7f4e8b0c15", "name": "price-list-eur.png", "contentType": "image/png", "size": 48213, "storage": "db", "createdAt": "2026-10-13T09:00:00.000Z", "createdBy": "6f1c2b3a-0000-4000-8000-0000000000a2"}No name (or one over 200 characters once cleaned), an empty file, or a text with nothing left once cleaned
object
Example generated
{ "error": "example"}No / invalid token or session
A reader of the project
object
Example generated
{ "error": "example"}Not found or not yours
object
Example generated
{ "error": "example"}It already has 20 pictures (or 10 texts, for a text)
object
Example generated
{ "error": "example"}A picture larger than 2 MiB, or a text larger than 512 KiB — as sent, or once cleaned; or the file fits the storage budget only if files of bugs went — their copies and attachments are never sent away (code: over_budget)
object
Example generated
{ "error": "example"}A type that is not listed — it needs the project’s bucket; a text in a charset other than UTF-8; or bytes that are not UTF-8 text
object
Example generated
{ "error": "example"}Rate-limited: the per-route throttle, or the per-minute request limit of the plan an API token counts by (#1442; the body names the plan, #2092). Retry-After carries the seconds until the window rolls over.
object
Example generated
{ "error": "example"}Headers
Section titled “Headers ”Seconds until the window rolls over