The storage, search and review API
Who can call raea's API (anyone on Pro or Team, on their own or in a team), how an agent key is made and scoped, and the calls for cloud libraries, search by meaning, files and review links.
Your cloud libraries, their search and your review links are reachable over HTTP at https://api.raea.io, so an
agent, a script or your own tool can find a shot, fetch it, add files, and share them for review. The raea app uses
the same calls.
Who can use it
Anyone on Pro or Team can, a person on their own included: there's no separate developer plan and no per-call price. The API reaches what lives in raea's cloud, so it comes with the plans that have cloud storage.
On Free, libraries stay on your Mac, and so does their search. Search them from the app, or from a terminal or an
agent on the same Mac with raea library, which needs no key. Asking for an agent key
on Free answers 402 agent_keys_paid.
Make an agent key
On raea.io/account, open Storage, then Agent access. Name the key after the agent that will
use it, tick what it may do, and pick which libraries it reaches (all of them, or some). The key, raea_ak_ and 64
hex characters, is shown once with a ready-made example: copy it then. raea keeps only its hash.
A key lasts 90 days unless you choose otherwise (365 at most), up to 50 at once. Revoking one stops it on its next request. Every change made with a key goes in your storage log, with the key's name.
Send it as a bearer header on every call. Nothing else works with it: no cookie, no basic auth.
curl https://api.raea.io/v1/libraries -H "authorization: Bearer raea_ak_..."What a key may do
| Scope | Reaches |
|---|---|
files:read | your libraries and their files, search, a file's download URL, storage used |
files:write | uploads, naming files in a cloud library, tags, new libraries and cloud sources |
files:delete | moving stored files to the trash, the trash, restoring from it |
share | review links: making, changing and stopping them, their comments; a project's collaborators |
A key reaches only those. Billing, connections, publishing, your computers, devices, Git LFS and the keys themselves
answer 403 agent_scope, whatever the key's scopes. A key limited to some libraries sees only their files (any other
is 404) and the files it uploaded itself; making a library, the trash and collaborators need a key for all of them.
Find your libraries
curl https://api.raea.io/v1/libraries -H "authorization: Bearer $RAEA_KEY"Each library comes with its id, name, workspace, sources (each with its kind: a folder or volume on one of
your computers, cloud, or drive for Google Drive), and how many files it holds and has indexed. A library on
your Mac only isn't here: it never leaves the Mac.
List a library's files, 200 at a time (up to 500), each with its path, sha256, kind and thumbnail:
curl "https://api.raea.io/v1/libraries/lib_.../files?limit=200" -H "authorization: Bearer $RAEA_KEY"Pass the last path you got as after= for the next page.
Search
curl https://api.raea.io/v1/libraries/search \
-H "authorization: Bearer $RAEA_KEY" -H "content-type: application/json" \
-d '{"workspace": "<a library'\''s workspace>", "words": "a chip pulled apart, cheese stretching", "limit": 10}'| Field | |
|---|---|
workspace | required: the workspace the libraries are in, as the list names it |
words | what you're looking for, as you'd describe it |
vector | the words' embedding, to search by meaning (below) |
libraries | a list: only these library ids |
kind | a list of any of video, image and audio |
tags | a list: only files with any of these tags |
path | a glob over the files' paths, like cuts/** |
limit | how many hits |
sound | true to rank by how things sound, for a described sound effect |
Each hit is a moment: the file's sha256, the segment's t0 and t1 in seconds, a score, what matched (its
picture, sound or words by meaning, its text or sound labels by keyword), any text read or heard in it, its
labels, a thumb_url, and the file with every place it's kept. The answer's by says how it searched.
By meaning, or by words. With vector, raea compares it with every shot's picture, sound and words, and matches
your words as keywords too: "by": "meaning". Without one, it searches by keywords alone: "by": "words". The vector
is EmbeddingGemma 2's (onnx-community/embeddinggemma-2-ONNX, 768 numbers) for the text
task: search result | query: followed by your words. raea never runs a model in its cloud for you: the app embeds
your words on your Mac, which is what raea library search and the app's Search do, and raea.io's Storage page
borrows one of your computers that's online.
Get a file
curl https://api.raea.io/v1/storage/blobs/<sha256> -H "authorization: Bearer $RAEA_KEY"The answer is a url good for an hour, and the file's size. Fetch the bytes from it directly. A file in a folder
on one of your computers is in storage only once something has uploaded it (sharing it does); until then the hit's
file says which computer has it.
Add a file
Files go straight to storage, never through the API. Ask with the file's SHA-256 and size:
curl https://api.raea.io/v1/storage/uploads -H "authorization: Bearer $RAEA_KEY" \
-H "content-type: application/json" -d '{"sha256": "<sha256>", "size": 1048576}'The answer is {"exists": true} when raea has the file already, a url to PUT it to, or for a big file an
upload_id with a URL for each part. Then POST /v1/storage/uploads/complete with {sha256, upload_id, parts} (each
part's n and etag). An upload past your plan's storage is refused before it starts.
To put it in a cloud library, name it in one of the library's cloud sources:
curl https://api.raea.io/v1/libraries/sources/<source id>/files -H "authorization: Bearer $RAEA_KEY" \
-H "content-type: application/json" \
-d '{"upsert": [{"path": "cuts/teaser.mp4", "sha256": "<sha256>", "size": 1048576, "mtime": 1794400000000, "kind": "video"}]}'raea doesn't index files on its own servers: one of your linked computers indexes it the next time it's online with
raea open, and then it turns up in search. The same call takes rename: [{from, to}], and remove: [path] with files:delete. Tags go on with POST /v1/libraries/media/<sha256>/tags
{"tags": [...]}.
Delete, with a way back
DELETE /v1/storage/blobs/<sha256> moves a file to the trash. It's refused (409 in_use, saying where) while a
library still names it or a post is going out with it. GET /v1/storage/trash lists the trash, and
POST /v1/storage/trash/<sha256>/restore brings a file back. raea deletes it for good after 30 days, and only you, on
raea.io, can empty the trash sooner.
Share for review
With the share scope, a key can send a stored file on a review link. Giving a key that scope is your say-so; Let
agents share, in the app's Settings, is the same choice for agents working inside the app.
curl https://api.raea.io/v1/review-links -H "authorization: Bearer $RAEA_KEY" \
-H "content-type: application/json" \
-d '{"sha256": "<sha256>", "type": "video/mp4", "title": "Teaser, cut 3", "days": 30}'The answer has the link's id and its url (raea.io/r/...) to hand on. days is 1 to 365 (30 if left out),
download lets reviewers download the file, and password sets one. The file must be in your storage first:
409 not_stored says to upload it.
| Call | |
|---|---|
GET /v1/review-links | every link, newest first |
GET /v1/review-links/<id> | one link with its versions, comments and viewers |
POST /v1/review-links/<id>/versions | {sha256, type}: the next version, on the same link |
POST /v1/review-links/<id>/comments | {body, version?, parent?}: your answer to a reviewer |
PATCH /v1/review-links/<id>/comments/<comment id> | {"resolved": true} |
PATCH /v1/review-links/<id> | {title?, days?, download?, password?} |
DELETE /v1/review-links/<id> | stop sharing: the link stops working for everyone at once |
A link of several files is made in the app for now (the Library's Share for review bar); a key can't make one yet.
Errors
A missing, unknown, revoked or expired key gets a plain-text 401. Every other refusal is JSON with an error code
and a message saying what to do: 402 for a plan without the feature, 403 agent_scope for a call outside the key's scopes, 404 for
anything that isn't yours (raea never says whether it exists), 409 for a conflict, and 413 when storage or the
search index is full.