Skip to main content
When your stimulus is a URL, just pass it on the evaluation create body. When it’s a screenshot, video, or PDF, use the file upload flow. The upload is a three-step signed-URL handshake — you talk to our API to get a signed URL, you PUT the bytes directly to Google Cloud Storage, then you tell us you’re done. No bytes ever traverse our origin.

Why three steps

  • Cost: signed URLs are free; piping 200MB videos through Vercel functions is not.
  • Speed: GCS regional edge upload beats round-tripping through us.
  • Security: we never see the file bytes; you never see our service account.

Flow

Then reference the fileId on designUrls[].fileId or comparisonPairs[].sideAFileId when creating an evaluation.

Step 1 — initialise

Response:
Signed URLs expire in 15 minutes.

Step 2 — PUT the bytes

Use the headers from step 1 verbatim. Adding extra headers will void the signature.
A successful PUT returns 204 No Content.

Step 3 — finalise

Finalise validates that the bytes actually landed and computes a sha256 checksum. Do not skip it — an unfinalised file is invisible to evaluation create.

Reading a file

The route gates on team membership and returns a short-lived signed GET URL. Render images directly from that URL; do not proxy them through your application.

Limits

Files are retained for the life of the evaluation. Deleting an evaluation deletes its files.

Doctor

A self-test endpoint to diagnose upload issues:
Returns a list of recent failed uploads on your team and the likely cause (signed URL expired, Content-Type mismatch, finalise never called).