Build a custom machine
SDK at a glance
Every call, grouped as the SDK reference groups them. Needs is the line machine.yaml must hold; a dash means nothing. Each name links to its full entry in the SDK reference.
The machine
| Call | Needs | Does |
|---|---|---|
sdk.machine(slug) | — | The machine object, m, for the folder's own slug. |
m.home | — | Its own address on the Ownbox, /my/<slug>. |
Settings and files
| Call | Needs | Does |
|---|---|---|
m.setting(key, default=None) | — | Reads a value it saved, or default. |
m.save_setting(key, value) | — | Saves a value, as JSON. |
m.data_dir() | — | Its own folder, for an SQLite file and larger files. |
Jobs
| Call | Needs | Does |
|---|---|---|
m.every(seconds, *, name=None) | — | Runs the decorated function on a schedule; the first run is due at once. |
The AI
| Call | Needs | Does |
|---|---|---|
m.think(task, prompt, *, system=None, max_tokens=1024) | think | Asks the Ownbox's AI, metered under its monthly allowance. |
The web and keys
| Call | Needs | Does |
|---|---|---|
m.fetch(url, *, method="GET", headers=None, body=None, key=None, timeout=20) | fetch, and keys for key= | Makes one https request, through the Ownbox. |
m.keys_page | — | The owner's page for this machine's keys and their monthly limits. |
m.secret(name, *, label=None, help="") | — | Always refused never_readable: a machine never reads a key. |
People
| Call | Needs | Does |
|---|---|---|
m.person(kind, value, *, name="", space=None) | people:write | The person behind an id, made the first time any machine meets them. |
m.touch(person, kind, ref="") | people:write | Records an event on their timeline. |
m.people_find(q=None, *, kind=None, limit=50, cursor=None, space=None) | people:read | The people the business met, a page at a time. |
m.people_timeline(person, *, limit=50, cursor=None) | people:read | What happened to one person, newest first. |
on_forget(person_id) | on_forget: true | A function the machine defines: erases one person from its own data. |
Conversations
| Call | Needs | Does |
|---|---|---|
m.messages(conversation, *, since=None) | conversations:read | A conversation's messages, oldest first. |
m.comments(*, post=None, since=None) | conversations:read | Recent comments on the business's Instagram account. |
m.conversation_for(comment) | conversations:read | The direct-message conversation with whoever wrote a comment. |
m.follows_you(conversation) | conversations:read | Whether they follow the account: True, False or None. |
m.claim(conversation, *, title, days=7, trigger=None) | conversations:write | Takes charge of a conversation in the inbox. |
m.release(conversation, *, note="") | conversations:write | Lets it go, or hands it to the team with a note. |
Sending
| Call | Needs | Does |
|---|---|---|
m.send_dm(conversation, text, *, key, buttons=None, quick_replies=None) | send: dm | One message on a conversation it claimed. |
m.reply_to_comment(comment, text, *, key, quick_replies=None) | send: dm | A private reply to a comment. |
m.send_email(person, draft, *, key, consent=None) | send: email | One email to a person who wrote in first. |
m.drafts(*, limit=50) | — | The emails the Ownbox kept for the owner to send. |
m.drop_draft(draft_id) | — | Lets one of its drafts go. |
The team and money
| Call | Needs | Does |
|---|---|---|
m.notify(member, text, *, key="notice") | — | Tells one team member one thing, in the next notice slot. |
m.spend(vendor, units=1, *, key) | keys, and the owner's monthly limit | Records a paid unit before the call that spends it. |
Approvals
| Call | Needs | Does |
|---|---|---|
m.propose(kind, *, title, detail=None) | — | Holds an action on Approvals until a person decides. |
m.on_approve(kind, fn) | — | Registers what runs, once, when a person says yes. |
The owner's AI and the Morning Review
| Call | Needs | Does |
|---|---|---|
m.tool(name, *, fn, description, args=None, title=None, render=None) | — | A question the owner's AI may ask the machine. |
m.reporter(title, fn) | — | Its part of the owner's Morning Review. |
m.day_window(day) | — | The UTC bounds of one of the Ownbox's local days. |
Pages and cards
| Call | Needs | Does |
|---|---|---|
m.screen(path, *, owner_only=False, title=None) | — | Declares a page at m.home or under it; the decorated function answers it. |
m.panel(slot, *, title, render) | — | Declares a card on another screen. |
m.link(path) | — | The full address of one of its pages. |
sdk.page(path, *, title, lede="", body) | — | A page as HTML, for a machine written before screen.json. |
Not yet. m.menu and m.activity raise sdk.NotYet with a sentence. m.store, m.query, m.media and
m.upload are reserved for later releases and raise sdk.Reserved, saying what to use until then.
m.tool also takes capability=, which only a machine that runs in-process uses: a custom machine's tool always
runs under the capability the Ownbox gives it, read:my_<key> (Routes and tools).