Era Desktop API
Every Era Desktop action (6) and data model (0): endpoints, scopes, input, preconditions, events and examples.
Your Era Desktop’s chats, approvals waiting, plans, todos and automations — kept in Era, yours only.
Module code station · 6 actions · 0 data models · 6 events. A key or token never does more here than the person behind it can; row-level security applies exactly as in the app. Scopes: station (everything), station:read (read only) or station:<capability>.
Actions
| Action | Needs | What it does |
|---|---|---|
station.answer_pending | station:write | Answer a Station request |
station.record_batch | station:write | Record Station facts |
station.toggle_automation | station:write | Pause or resume a Station automation |
station.update_automation | station:write | Change a Station automation |
station.update_thread | station:write | Change a Station chat |
station.update_todo | station:write | Change a Station todo |
station.answer_pending
Answer a Station request — Approve, decline or answer what your Station is waiting on, from the web; the Station continues with it.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.answer_pendingInput
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Request · id of station_pending |
answer | object / array | yes | Answer |
via | string (enum) | From · Allowed values: web, phone |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
pending_not_found | The request must be one Era keeps for this workspace. |
not_your_pending | Only the person the Station works for answers it. |
already_answered | A request is answered once. |
invalid_answer | The answer is an object: a decision, or the answers to the questions. |
Events it publishes: station.pending_answered
What it writes: station_pending (update) — Records the answer; the Station picks it up
curl -X POST https://app.getera.io/api/v1/actions/station.answer_pending \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"STATION_PENDING_ID","answer":{}}'{
"ok": true,
"result": "…",
"events": [
"station.pending_answered"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.answer_pending", {
id: "STATION_PENDING_ID",
answer: {}
})era station answer_pending --data '{"id":"STATION_PENDING_ID","answer":{}}'{
"name": "era__station__answer_pending",
"arguments": {
"id": "STATION_PENDING_ID",
"answer": {}
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 pending_not_found, not_your_pending, already_answered, invalid_answer · 429 slow down
station.record_batch
Record Station facts — What a Station settled since its last batch — projects, chats, approvals waiting, plans, todos, automations — kept in Era as yours.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.record_batchInput
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | uuid | Station · The paired key of the Station that settled these facts. | |
items | object / array | yes | Facts |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
invalid_batch | A batch is a list of at most 500 items. |
not_your_device | The Station must be paired to the caller in this workspace. |
Events it publishes: station.batch_recorded
What it writes: station_engine (upsert) — Locked engine sequence and projection/runtime checkpoint; station_event (insert) — Ordered settled engine facts; transient deltas are refused; station_receipt (insert) — Immutable batch acknowledgments for safe retries; station_checkpoint_part (insert) — Immutable bounded checkpoint parts; a complete manifest is activated atomically; station_space (upsert) — Spaces; station_project (upsert) — Projects (folders); station_thread (upsert) — Chat settings; a web edit newer than the device copy wins; station_pending (upsert) — Approvals and questions waiting; an answer given on the web stays; station_plan (upsert) — Proposed plans; station_todo (upsert) — Todos; station_pr_pin (upsert) — Pinned pull requests, 20 per project; station_automation (upsert) — Automations; station_automation_run (upsert) — Automation runs; station_automation_memory (upsert) — What an automation remembers
curl -X POST https://app.getera.io/api/v1/actions/station.record_batch \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"items":{}}'{
"ok": true,
"result": "…",
"events": [
"station.batch_recorded"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.record_batch", {
items: {}
})era station record_batch --data '{"items":{}}'{
"name": "era__station__record_batch",
"arguments": {
"items": {}
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 invalid_batch, not_your_device · 429 slow down
station.toggle_automation
Pause or resume a Station automation — Stops one of your Station automations from running, or lets it run again.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.toggle_automationInput
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Automation · id of station_automation |
enabled | boolean | yes | Runs |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
automation_not_found | The automation must be one Era keeps for this workspace. |
not_your_automation | Only its owner pauses an automation. |
Events it publishes: station.automation_toggled
What it writes: station_automation (update) — On or off; the Station follows
curl -X POST https://app.getera.io/api/v1/actions/station.toggle_automation \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"STATION_AUTOMATION_ID","enabled":true}'{
"ok": true,
"result": "…",
"events": [
"station.automation_toggled"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.toggle_automation", {
id: "STATION_AUTOMATION_ID",
enabled: true
})era station toggle_automation \
--id "STATION_AUTOMATION_ID" \
--enabled true{
"name": "era__station__toggle_automation",
"arguments": {
"id": "STATION_AUTOMATION_ID",
"enabled": true
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 automation_not_found, not_your_automation · 429 slow down
station.update_automation
Change a Station automation — Rename one of your Station automations, change what it asks or when it runs.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.update_automationInput
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Automation · id of station_automation |
title | string | Name · max 500 | |
prompt | string | What it asks · max 50000 | |
schedule | object / array | When |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
automation_not_found | The automation must be one Era keeps for this workspace. |
not_your_automation | Only its owner changes an automation. |
invalid_schedule | A schedule is an object. |
Events it publishes: station.automation_updated
What it writes: station_automation (update) — The person’s edit; the Station applies it
curl -X POST https://app.getera.io/api/v1/actions/station.update_automation \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"STATION_AUTOMATION_ID"}'{
"ok": true,
"result": "…",
"events": [
"station.automation_updated"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.update_automation", {
id: "STATION_AUTOMATION_ID"
})era station update_automation \
--id "STATION_AUTOMATION_ID"{
"name": "era__station__update_automation",
"arguments": {
"id": "STATION_AUTOMATION_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 automation_not_found, not_your_automation, invalid_schedule · 429 slow down
station.update_thread
Change a Station chat — Pin, archive, snooze or rename one of your Station chats, keep notes on it, or share it with the workspace.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.update_threadInput
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Chat · id of station_thread |
title | string | Title · max 1000 | |
isPinned | boolean | Pinned | |
archived | boolean | Archived | |
snoozedUntil | date-time | Snoozed until | |
notes | string | Notes · max 20000 | |
visibility | string (enum) | Who sees it · Allowed values: private, workspace |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
thread_not_found | The chat must be one Era keeps for this workspace. |
not_your_thread | Only the chat’s owner changes it, even when it is shared. |
Events it publishes: station.thread_updated
What it writes: station_thread (update) — The person’s own settings for the chat
curl -X POST https://app.getera.io/api/v1/actions/station.update_thread \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"STATION_THREAD_ID"}'{
"ok": true,
"result": "…",
"events": [
"station.thread_updated"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.update_thread", {
id: "STATION_THREAD_ID"
})era station update_thread \
--id "STATION_THREAD_ID"{
"name": "era__station__update_thread",
"arguments": {
"id": "STATION_THREAD_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 thread_not_found, not_your_thread · 429 slow down
station.update_todo
Change a Station todo — Rename one of your Station todos or tick it off.
Needs station:write · changes data
https://app.getera.io/api/v1/actions/station.update_todoInput
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Todo · id of station_todo |
title | string | Todo · max 2000 | |
done | boolean | Done |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
todo_not_found | The todo must be one Era keeps for this workspace. |
not_your_todo | Only its owner changes a todo. |
empty_title | A todo says something. |
Events it publishes: station.todo_updated
What it writes: station_todo (update) — The person’s edit; the Station applies it
curl -X POST https://app.getera.io/api/v1/actions/station.update_todo \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"STATION_TODO_ID"}'{
"ok": true,
"result": "…",
"events": [
"station.todo_updated"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("station.update_todo", {
id: "STATION_TODO_ID"
})era station update_todo \
--id "STATION_TODO_ID"{
"name": "era__station__update_todo",
"arguments": {
"id": "STATION_TODO_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold station:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 todo_not_found, not_your_todo, empty_title · 429 slow down
Events
Workflows and webhooks react to these events.
| Event | What happens | Payload |
|---|---|---|
station.automation_toggled | A person paused or resumed a Station automation. | id, localId, deviceId, enabled |
station.automation_updated | A person changed a Station automation. | id, localId, deviceId |
station.batch_recorded | A Station sent what it settled. | deviceId, applied, kinds |
station.pending_answered | A person answered what their Station was waiting on. | id, localId, deviceId, threadId |
station.thread_updated | A person changed one of their Station chats from Era. | id, localId, deviceId |
station.todo_updated | A person changed a Station todo. | id, localId, deviceId |