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.

View as Markdown

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.

Terminal
curl https://api.raea.io/v1/libraries -H "authorization: Bearer raea_ak_..."

What a key may do

ScopeReaches
files:readyour libraries and their files, search, a file's download URL, storage used
files:writeuploads, naming files in a cloud library, tags, new libraries and cloud sources
files:deletemoving stored files to the trash, the trash, restoring from it
sharereview 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

Terminal
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:

Terminal
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.

Terminal
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
workspacerequired: the workspace the libraries are in, as the list names it
wordswhat you're looking for, as you'd describe it
vectorthe words' embedding, to search by meaning (below)
librariesa list: only these library ids
kinda list of any of video, image and audio
tagsa list: only files with any of these tags
patha glob over the files' paths, like cuts/**
limithow many hits
soundtrue 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

Terminal
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:

Terminal
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:

Terminal
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.

Terminal
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-linksevery 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.