{"openapi":"3.1.0","info":{"title":"Terebyte API","version":"0.1.2","summary":"Encrypted storage for AI agents and programs: an account of their own, or a door into a member's room.","description":"Everything stored is encrypted on the program's own computer before it's sent; Terebyte keeps sealed bytes. Use the kits (`npx terebyte`, `pip install terebyte`): they do the encryption, sign each request and keep the keys. The path for a program: buy (a prepaid code), create (POST /api/agents/accounts), get its keys (made on its computer; a device token comes back), use (its own vault, or doors members give it). Its owner claims the account later with the claim link.","termsOfService":"https://terebyte.com/terms/api","contact":{"email":"support@terebyte.com"}},"servers":[{"url":"https://terebyte.com"}],"externalDocs":{"description":"Developer docs","url":"https://terebyte.com/developers"},"components":{"securitySchemes":{"deviceToken":{"type":"http","scheme":"bearer","description":"The device token an account's program gets when it's made (tbd_…). Keep it like a password."},"door":{"type":"apiKey","in":"header","name":"Authorization","description":"A door's request, signed by the kit with the agent's own key. Use the kits for these."}}},"paths":{"/api/words/challenge":{"post":{"summary":"A challenge to sign","description":"A one-time challenge for making an account, or signing in, with 12 words. The words are made and kept on the program's computer; only a public key and a signature are sent.","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The challenge, and how much work goes with it.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/agents/accounts":{"post":{"summary":"Buy an account","description":"An account of the program's own, paid by a prepaid code (no free tier by the API): the signed challenge, the vault's proof and the code. Under the API Terms, an account a program makes is its owner's responsibility. Answers with a device token.","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"201":{"description":"Made: the device token, the plan and until when.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"403":{"description":"New accounts are paused."},"409":{"description":"The code was already redeemed."},"429":{"description":"Too many requests for now."}}}},"/api/blocks":{"post":{"summary":"Make room for sealed blocks","description":"Where to send the program's sealed blocks (its own account).","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Where to send them.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"get":{"summary":"List the account's blocks","security":[{"deviceToken":[]}],"responses":{"200":{"description":"A page of blocks.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/blocks/read":{"post":{"summary":"Fetch sealed blocks","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Where to fetch them.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/blocks/touch":{"post":{"summary":"Blocks still being sent","description":"Marks blocks an upload under way still needs.","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"How many.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/blocks/schedule":{"post":{"summary":"Blocks for the trash","description":"Deletes blocks at a time given, or never.","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"How many.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/blocks/delete":{"post":{"summary":"Delete sealed blocks","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"How many went.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/index":{"get":{"summary":"Read the account's sealed index","security":[{"deviceToken":[]}],"responses":{"200":{"description":"A page of sealed records.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"post":{"summary":"Add to the account's sealed index","security":[{"deviceToken":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Stored.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/pair":{"post":{"summary":"Start pairing","description":"The 6-character code a member types in their app to give an agent a door.","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The code's part from the server, and until when.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"put":{"summary":"Carry on pairing","description":"The agent's side of the exchange, until the member approves or the code ends.","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"What the member's side sent so far.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/door":{"get":{"summary":"This door","description":"The room it opens, what it may do, and until when.","security":[{"door":[]}],"responses":{"200":{"description":"The door.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/door/records":{"get":{"summary":"The room's records","description":"The room's sealed records after a point.","security":[{"door":[]}],"responses":{"200":{"description":"A page of sealed records.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"post":{"summary":"Add a record","description":"A sealed record: a file's new version, a note on the board, a claim.","security":[{"door":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Stored.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"403":{"description":"The door doesn't allow it, or it's paused or closed."},"429":{"description":"Too many requests for now."}}}},"/api/door/blocks":{"post":{"summary":"The room's sealed blocks","description":"Make room for, fetch or delete the room's sealed blocks, as the door allows.","security":[{"door":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Where to send or fetch them.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/door/listen":{"get":{"summary":"Wait for changes","description":"Answers when something changes in the room, or after a while.","security":[{"door":[]}],"responses":{"200":{"description":"What changed.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/door/shares":{"post":{"summary":"Make a Sealed Link","description":"A link to a file's current version for someone outside the room (the door needs Share).","security":[{"door":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The link's part from the server.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/valet/errand":{"post":{"summary":"Ask for an errand","description":"Under a valet key the member gave the agent: an errand sealed to the member's own computer, which runs it within the member's limits. The answer is \"not done\" until it's done; never why.","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Its id, and \"not done\" for now.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"get":{"summary":"How an errand went","description":"\"done\" and a reference, or \"not done\".","responses":{"200":{"description":"Its status.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/valet/executor":{"get":{"summary":"The member's executor: errands due","description":"For the member's own computer only: the errands whose waiting time has passed.","responses":{"200":{"description":"The errands, sealed.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}},"post":{"summary":"The member's executor: how one went","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Kept.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/log/head":{"get":{"summary":"The public log's signed head","responses":{"200":{"description":"Its size, root and signature.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/log/proof":{"get":{"summary":"An entry's place in the public log","responses":{"200":{"description":"The proof.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/log/entries":{"get":{"summary":"The public log's entries","responses":{"200":{"description":"A page of entries.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}},"/api/with/{code}":{"get":{"summary":"A pass","description":"A Meter's, Toll's or Ticket's pass, opened with its code.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The pass.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request isn't valid."},"401":{"description":"Not signed in."},"429":{"description":"Too many requests for now."}}}}}}