ReferenceReference by module

Platform API

Every Platform action (19) and data model (1): endpoints, scopes, input, preconditions, events and examples.

API keys, webhooks and background jobs for connecting other tools.

Module code platform · 19 actions · 1 data models · 16 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: platform (everything), platform:read (read only) or platform:<capability>.

Resources

ResourceTableList and readPOSTPATCHDELETE
event_subscriber_skipsevent_subscriber_skip/api/v1/event_subscriber_skips

Lists take limit (up to 200), cursor, order (e.g. -created_at), fields and q; every other query parameter is a column filter: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.

Actions

ActionNeedsWhat it does
platform.cancel_jobplatform:manageCancel a job
platform.create_api_keyplatform:manageCreate an API key
platform.create_webhookplatform:manageRegister a webhook
platform.delete_webhookplatform:deleteRemove a webhook
platform.end_session_keyplatform:readEnd an Era session key
platform.enqueue_jobplatform:handleQueue work
platform.issue_session_keyplatform:readStart an Era session key
platform.issue_station_keyplatform:readStart Era’s engine for me
platform.pair_deviceplatform:readPair my computer
platform.purge_historyplatform:deleteSweep delivery history
platform.record_deliveryplatform:handleRecord a webhook delivery
platform.rename_api_keyplatform:manageRename an API key
platform.retry_jobplatform:manageRetry a job
platform.revoke_api_keyplatform:manageRevoke an API key
platform.rotate_webhook_secretplatform:manageRotate a signing secret
platform.send_test_deliveryplatform:manageSend a test or replay a delivery
platform.set_webhook_activeplatform:manageSwitch a webhook on or off
platform.unpair_deviceplatform:readRemove my computer
platform.update_webhookplatform:manageEdit a webhook

platform.cancel_job

Cancel a job — Takes a queued job off the queue. A job already running is left alone.

Needs platform:manage · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/actions/platform.cancel_job
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
job_iduuidyesJob

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
job_not_foundNo such job in this workspace.
job_already_finishedThat job has already finished.
job_runningThat job is running and cannot be cancelled from here.

Events it publishes: platform.job_cancelled

What it writes: job (update) — Marks the job cancelled

curl -X POST https://app.getera.io/api/v1/actions/platform.cancel_job \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"job_id":"JOB_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.job_cancelled"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.cancel_job", {
  job_id: "JOB_ID"
})
era platform cancel_job \
  --job-id "JOB_ID"
tools/call
{
  "name": "era__platform__cancel_job",
  "arguments": {
    "job_id": "JOB_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 job_not_found, job_already_finished, job_running · 429 slow down

platform.create_api_key

Create an API key — Issues a key for this workspace. The key itself is shown once and never stored.

Needs platform:manage · changes data

Only from the Era app: this action creates credentials, so a key or a token is refused (403).
POSThttps://app.getera.io/api/v1/actions/platform.create_api_key
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
namestringyesName · What this key is for. It is the only thing that will identify it later. · max 120
key_hashstringyesKey digest · SHA-256 of the key. The key itself never reaches the server twice. · max 64
key_prefixstringyesKey prefix · The first few characters, so the key can be told apart on screen. · max 16
scopesstringModules · Comma-separated module codes. Leave empty to inherit whatever the creator holds. · max 500
expires_atdate-timeExpires

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_a_digestThe key digest must be a SHA-256 hash, not the key itself.
name_takenThis workspace already has a key with that name.
expiry_in_pastThe expiry date has already passed.
key_limit_reachedThis workspace already has the maximum number of live keys.

Events it publishes: platform.key_created

What it writes: api_key (insert) — Stores the digest, the prefix and who issued it

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_a_digest, name_taken, expiry_in_past, key_limit_reached · 429 slow down

platform.create_webhook

Register a webhook — An endpoint this workspace posts to, or one the outside world posts to.

Needs platform:manage · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/actions/platform.create_webhook
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
directionstring (enum)yesDirection · Allowed values: outbound, inbound
namestringyesName · max 120
target_urlstringURL · Outbound only. · max 2000
pathstringPath · Inbound only. The last segment of the address they post to. · max 80
eventsstringEvents · Comma-separated. Leave empty for every event. · max 1000
secret_hashstringSigning secret digest · Inbound only: SHA-256 of the shared secret used to verify signatures. · max 64
credential_iduuidCredential · Outbound only: the credential holding the signing secret.
timeout_msnumberTimeout (ms) · Outbound only. How long to wait for the receiver. · min 1000 · max 30000
max_attemptsnumberAttempts · Outbound only. Tries before a delivery is given up on. · min 1 · max 10
rate_limit_per_minutenumberRequests per minute · Inbound only. Per caller address; 0 means unlimited. · min 0 · max 6000

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
address_missingAn outbound webhook needs a URL and an inbound one needs a path.
invalid_urlThat does not look like a web address.
insecure_urlThe address must use https.
invalid_pathThe path may contain only lowercase letters, numbers, hyphens and underscores.
path_takenAnother endpoint already answers on that path.
name_takenThis workspace already has a webhook with that name.
not_a_digestThe signing secret digest must be a SHA-256 hash, not the secret itself.
unsigned_inboundAn inbound webhook must carry a signing secret.

Events it publishes: platform.webhook_created

What it writes: webhook (insert) — Registers the endpoint, inactive failures counted from zero

curl -X POST https://app.getera.io/api/v1/actions/platform.create_webhook \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"direction":"outbound","name":"Name"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.webhook_created"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.create_webhook", {
  direction: "outbound",
  name: "Name"
})
era platform create_webhook \
  --direction "outbound" \
  --name "Name"
tools/call
{
  "name": "era__platform__create_webhook",
  "arguments": {
    "direction": "outbound",
    "name": "Name"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 address_missing, invalid_url, insecure_url, invalid_path, path_taken, name_taken, not_a_digest, unsigned_inbound · 429 slow down

platform.delete_webhook

Remove a webhook — Removes the endpoint and its delivery history.

Needs platform:delete · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/actions/platform.delete_webhook
API key or OAuth token · platform:delete

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.

Events it publishes: platform.webhook_deleted

What it writes: webhook (delete) — Removes the endpoint; its deliveries cascade

curl -X POST https://app.getera.io/api/v1/actions/platform.delete_webhook \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.webhook_deleted"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.delete_webhook", {
  webhook_id: "WEBHOOK_ID"
})
era platform delete_webhook \
  --webhook-id "WEBHOOK_ID"
tools/call
{
  "name": "era__platform__delete_webhook",
  "arguments": {
    "webhook_id": "WEBHOOK_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found · 429 slow down

platform.end_session_key

End an Era session key — Revokes the short-lived key Era’s engine used for one run, as soon as that run ends.

Needs platform:read · changes data

Only from the Era app: this action creates credentials, so a key or a token is refused (403).
POSThttps://app.getera.io/api/v1/actions/platform.end_session_key
API key or OAuth token · platform:read

Input

FieldTypeRequiredNotes
key_iduuidyesSession key

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
session_key_not_foundNo live Era session key with that id in this workspace.
not_your_session_keyOnly the person an Era session key acts for can end it, and only a session key.

Events it publishes: platform.key_revoked

What it writes: api_key (update) — Stamps the session key revoked

Errors: 401 no or expired credential · 403 the credential does not hold platform:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 session_key_not_found, not_your_session_key · 429 slow down

platform.enqueue_job

Queue work — Adds a job for a worker to claim. Re-queuing with the same key returns the first job.

Needs platform:handle · changes data

POSThttps://app.getera.io/api/v1/actions/platform.enqueue_job
API key or OAuth token · platform:handle

Input

FieldTypeRequiredNotes
typestringyesType · max 80
payloadstringPayload · JSON. Large for an import job (crm.import_leads carries its rows). · max 20000000
run_atdate-timeRun at · Leave empty to run as soon as a worker is free.
max_attemptsnumberAttempts · min 1 · max 20
idempotency_keystringIdempotency key · max 200

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
invalid_payloadThe payload must be a JSON object.
queue_fullThis workspace already has the maximum number of queued jobs.

Events it publishes: platform.job_enqueued

What it writes: job (insert) — Adds the job, pending, due at run_at

curl -X POST https://app.getera.io/api/v1/actions/platform.enqueue_job \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"type":"Type"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.job_enqueued"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.enqueue_job", {
  type: "Type"
})
era platform enqueue_job \
  --type "Type"
tools/call
{
  "name": "era__platform__enqueue_job",
  "arguments": {
    "type": "Type"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 invalid_payload, queue_full · 429 slow down

platform.issue_session_key

Start an Era session key — A short-lived key that lets Era’s engine use Era’s tools as you while it works on your request.

Needs platform:read · changes data

Only from the Era app: this action creates credentials, so a key or a token is refused (403).
POSThttps://app.getera.io/api/v1/actions/platform.issue_session_key
API key or OAuth token · platform:read

Input

FieldTypeRequiredNotes
key_hashstringyesKey digest · max 64
key_prefixstringyesKey prefix · max 16
expires_atdate-timeyesExpires
parent_key_iduuidIssued under · Your paired computer (or Era engine) key; revoking it revokes this one.

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_a_digestThe key digest must be a SHA-256 hash, not the key itself.
session_too_longA session key must expire in the future, within six hours.
parent_key_not_foundThe key it is issued under must be your own live computer or Era engine key in this workspace.

Events it publishes: platform.key_created

What it writes: api_key (insert) — Stores the session key’s digest, scoped to Era sessions and this person

Errors: 401 no or expired credential · 403 the credential does not hold platform:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_a_digest, session_too_long, parent_key_not_found · 429 slow down

platform.issue_station_key

Start Era’s engine for me — A key Era’s own engine uses to answer your chats as you, while your computer is off.

Needs platform:read · changes data

Only from the Era app: this action creates credentials, so a key or a token is refused (403).
POSThttps://app.getera.io/api/v1/actions/platform.issue_station_key
API key or OAuth token · platform:read

Input

FieldTypeRequiredNotes
key_hashstringyesKey digest · max 64
key_prefixstringyesKey prefix · max 16
expires_atdate-timeyesExpires

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_a_digestThe key digest must be a SHA-256 hash, not the key itself.
station_key_too_longAn engine key must expire in the future, within eight days.

Events it publishes: platform.key_created, platform.key_revoked

What it writes: api_key (insert) — Stores the engine key’s digest, scoped to Era’s engine and this person; api_key (update) — Revokes the person’s earlier engine keys

Errors: 401 no or expired credential · 403 the credential does not hold platform:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_a_digest, station_key_too_long · 429 slow down

platform.pair_device

Pair my computer — Connects your own computer (Era Desktop or your cloud computer) to Era so your subscriptions and tasks can run on it.

Needs platform:read · changes data

Only from the Era app: this action creates credentials, so a key or a token is refused (403).
POSThttps://app.getera.io/api/v1/actions/platform.pair_device
API key or OAuth token · platform:read

Input

FieldTypeRequiredNotes
namestringyesComputer · max 120
key_hashstringyesKey digest · max 64
key_prefixstringyesKey prefix · max 16
replacesstringReplaces · Your earlier pairing of the same computer, by name. · max 120

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_a_digestThe key digest must be a SHA-256 hash, not the key itself.
device_limit_reachedYou already have ten computers paired.
computer_access_requiredOnly the workspace owner, or a member given computer access, can reach a computer.

Events it publishes: platform.key_created, platform.key_revoked

What it writes: api_key (insert) — Stores the device key’s digest, scoped to this computer and this person; api_key (update) — Revokes the person’s earlier pairing of the same computer

Errors: 401 no or expired credential · 403 the credential does not hold platform:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_a_digest, device_limit_reached, computer_access_required · 429 slow down

platform.purge_history

Sweep delivery history — Removes delivery records older than the retention window, and expired idempotency keys.

Needs platform:delete · removes or cannot be undone

POSThttps://app.getera.io/api/v1/actions/platform.purge_history
API key or OAuth token · platform:delete

Input

FieldTypeRequiredNotes
daysnumberKeep for (days) · max 3650

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
retention_too_shortRetention must be at least one day.

Events it publishes: platform.history_purged

What it writes: webhook_delivery (delete) — Removes delivery attempts older than the window; idempotency_key (delete) — Removes keys whose window has passed

curl -X POST https://app.getera.io/api/v1/actions/platform.purge_history \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"days":1}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.history_purged"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.purge_history", {
  days: 1
})
era platform purge_history \
  --days 1
tools/call
{
  "name": "era__platform__purge_history",
  "arguments": {
    "days": 1
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 retention_too_short · 429 slow down

platform.record_delivery

Record a webhook delivery — One row per attempt, with the response and how long it took.

Needs platform:handle · changes data

POSThttps://app.getera.io/api/v1/actions/platform.record_delivery
API key or OAuth token · platform:handle

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook
event_namestringyesEvent · max 120
successbooleanyesSucceeded
attemptnumberAttempt · min 1 · max 100
idempotency_keystringIdempotency key · max 200
response_statusnumberResponse status · min 100 · max 599
response_bodystringResponse body · max 8000
error_messagestringError · max 2000
duration_msnumberDuration (ms) · min 0
request_bodystringBody sent · JSON. Kept so the attempt can be replayed byte for byte. · max 262144
event_idstringEvent · max 64

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.
duplicate_attemptThat attempt has already been recorded.

Events it publishes: platform.delivery_recorded, platform.webhook_disabled

What it writes: webhook_delivery (insert) — Writes the attempt; webhook (update) — Moves the consecutive-failure count, and disables the endpoint when it crosses the threshold

curl -X POST https://app.getera.io/api/v1/actions/platform.record_delivery \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID","event_name":"Event","success":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.delivery_recorded",
    "platform.webhook_disabled"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.record_delivery", {
  webhook_id: "WEBHOOK_ID",
  event_name: "Event",
  success: true
})
era platform record_delivery \
  --webhook-id "WEBHOOK_ID" \
  --event-name "Event" \
  --success true
tools/call
{
  "name": "era__platform__record_delivery",
  "arguments": {
    "webhook_id": "WEBHOOK_ID",
    "event_name": "Event",
    "success": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found, duplicate_attempt · 429 slow down

platform.rename_api_key

Rename an API key — The name is the only thing that identifies a key once it has been issued.

Needs platform:manage · changes data

POSThttps://app.getera.io/api/v1/actions/platform.rename_api_key
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
key_iduuidyesKey
namestringyesName · max 120

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
key_not_foundNo such key in this workspace.
name_takenThis workspace already has a key with that name.
already_revokedA revoked key cannot be renamed — its name is part of the record.

Events it publishes: platform.key_renamed

What it writes: api_key (update) — Changes the key’s name

curl -X POST https://app.getera.io/api/v1/actions/platform.rename_api_key \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"key_id":"KEY_ID","name":"Name"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.key_renamed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.rename_api_key", {
  key_id: "KEY_ID",
  name: "Name"
})
era platform rename_api_key \
  --key-id "KEY_ID" \
  --name "Name"
tools/call
{
  "name": "era__platform__rename_api_key",
  "arguments": {
    "key_id": "KEY_ID",
    "name": "Name"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 key_not_found, name_taken, already_revoked · 429 slow down

platform.retry_job

Retry a job — Puts a failed job back on the queue, due now.

Needs platform:manage · changes data

POSThttps://app.getera.io/api/v1/actions/platform.retry_job
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
job_iduuidyesJob

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
job_not_foundNo such job in this workspace.
job_not_failedOnly a failed job can be retried.
attempts_exhaustedThat job has already used all of its attempts.

Events it publishes: platform.job_retried

What it writes: job (update) — Returns the job to pending, due now, and raises its attempt ceiling by one

curl -X POST https://app.getera.io/api/v1/actions/platform.retry_job \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"job_id":"JOB_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.job_retried"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.retry_job", {
  job_id: "JOB_ID"
})
era platform retry_job \
  --job-id "JOB_ID"
tools/call
{
  "name": "era__platform__retry_job",
  "arguments": {
    "job_id": "JOB_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 job_not_found, job_not_failed, attempts_exhausted · 429 slow down

platform.revoke_api_key

Revoke an API key — Stops the key working immediately. The record stays so old requests can still be explained.

Needs platform:manage · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/actions/platform.revoke_api_key
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
key_iduuidyesKey

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
key_not_foundNo such key in this workspace.
already_revokedThat key was already revoked.

Events it publishes: platform.key_revoked

What it writes: api_key (update) — Stamps the key revoked, and by whom

curl -X POST https://app.getera.io/api/v1/actions/platform.revoke_api_key \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"key_id":"KEY_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.key_revoked"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.revoke_api_key", {
  key_id: "KEY_ID"
})
era platform revoke_api_key \
  --key-id "KEY_ID"
tools/call
{
  "name": "era__platform__revoke_api_key",
  "arguments": {
    "key_id": "KEY_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 key_not_found, already_revoked · 429 slow down

platform.rotate_webhook_secret

Rotate a signing secret — Issues a new secret. The old one keeps working for 24 hours.

Needs platform:manage · reaches outside (sends, publishes or charges) · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/actions/platform.rotate_webhook_secret
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook
secret_hashstringNew secret digest · Inbound only: SHA-256 of the new shared secret. · max 64

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.
digest_requiredAn inbound endpoint is rotated by sending the digest of its new secret.
not_a_digestThe signing secret digest must be a SHA-256 hash, not the secret itself.

Events it publishes: platform.webhook_secret_rotated

What it writes: webhook (update) — Moves the current secret to the overlap slot and stores the new one

curl -X POST https://app.getera.io/api/v1/actions/platform.rotate_webhook_secret \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.webhook_secret_rotated"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.rotate_webhook_secret", {
  webhook_id: "WEBHOOK_ID"
})
era platform rotate_webhook_secret \
  --webhook-id "WEBHOOK_ID"
tools/call
{
  "name": "era__platform__rotate_webhook_secret",
  "arguments": {
    "webhook_id": "WEBHOOK_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found, digest_required, not_a_digest · 429 slow down

platform.send_test_delivery

Send a test or replay a delivery — Queues a signed delivery to the endpoint. With replay_of, resends that attempt’s exact body.

Needs platform:manage · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/actions/platform.send_test_delivery
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook
replay_ofuuidDelivery to replay · Leave empty to send a test event.

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.
not_outboundOnly an endpoint this workspace calls can be sent a delivery.
webhook_inactiveThe endpoint is switched off.
nothing_to_replayThat delivery kept no body to resend.

Events it publishes: platform.test_delivery_queued

What it writes: job (insert) — Queues an apps.deliver job for the endpoint

curl -X POST https://app.getera.io/api/v1/actions/platform.send_test_delivery \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.test_delivery_queued"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.send_test_delivery", {
  webhook_id: "WEBHOOK_ID"
})
era platform send_test_delivery \
  --webhook-id "WEBHOOK_ID"
tools/call
{
  "name": "era__platform__send_test_delivery",
  "arguments": {
    "webhook_id": "WEBHOOK_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found, not_outbound, webhook_inactive, nothing_to_replay · 429 slow down

platform.set_webhook_active

Switch a webhook on or off — Switching one back on clears the failure count, so the disable threshold starts again.

Needs platform:manage · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/actions/platform.set_webhook_active
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook
activebooleanyesActive

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.
no_changeThe webhook is already in that state.

Events it publishes: platform.webhook_enabled, platform.webhook_disabled

What it writes: webhook (update) — Flips the active flag and, when enabling, resets the failure count

curl -X POST https://app.getera.io/api/v1/actions/platform.set_webhook_active \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID","active":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.webhook_enabled",
    "platform.webhook_disabled"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.set_webhook_active", {
  webhook_id: "WEBHOOK_ID",
  active: true
})
era platform set_webhook_active \
  --webhook-id "WEBHOOK_ID" \
  --active true
tools/call
{
  "name": "era__platform__set_webhook_active",
  "arguments": {
    "webhook_id": "WEBHOOK_ID",
    "active": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found, no_change · 429 slow down

platform.unpair_device

Remove my computer — Disconnects one of your own computers from Era. Its sign-ins stay on that computer.

Needs platform:read · reaches outside (sends, publishes or charges) · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/actions/platform.unpair_device
API key or OAuth token · platform:read

Input

FieldTypeRequiredNotes
key_iduuidyesComputer

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
key_not_foundNo such computer in this workspace.
not_your_deviceOnly the person who paired a computer can remove it here.

Events it publishes: platform.key_revoked

What it writes: api_key (update) — Stamps the device key revoked, and by whom

curl -X POST https://app.getera.io/api/v1/actions/platform.unpair_device \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"key_id":"KEY_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.key_revoked"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.unpair_device", {
  key_id: "KEY_ID"
})
era platform unpair_device \
  --key-id "KEY_ID"
tools/call
{
  "name": "era__platform__unpair_device",
  "arguments": {
    "key_id": "KEY_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 key_not_found, not_your_device · 429 slow down

platform.update_webhook

Edit a webhook — Name, address, events, timeout, attempts and inbound rate limit.

Needs platform:manage · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/actions/platform.update_webhook
API key or OAuth token · platform:manage

Input

FieldTypeRequiredNotes
webhook_iduuidyesWebhook
namestringName · max 120
target_urlstringURL · Outbound only. · max 2000
eventsstringEvents · Comma-separated. Empty means every event. · max 1000
timeout_msnumberTimeout (ms) · min 1000 · max 30000
max_attemptsnumberAttempts · min 1 · max 10
rate_limit_per_minutenumberRequests per minute · min 0 · max 6000

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
webhook_not_foundNo such webhook in this workspace.
name_takenThis workspace already has a webhook with that name.
invalid_urlThat does not look like a web address.
insecure_urlThe address must use https.

Events it publishes: platform.webhook_updated

What it writes: webhook (update) — Rewrites the endpoint’s settings

curl -X POST https://app.getera.io/api/v1/actions/platform.update_webhook \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"webhook_id":"WEBHOOK_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "platform.webhook_updated"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.actions.run("platform.update_webhook", {
  webhook_id: "WEBHOOK_ID"
})
era platform update_webhook \
  --webhook-id "WEBHOOK_ID"
tools/call
{
  "name": "era__platform__update_webhook",
  "arguments": {
    "webhook_id": "WEBHOOK_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold platform:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 webhook_not_found, name_taken, invalid_url, insecure_url · 429 slow down

Data models

EventSubscriberSkip

Table event_subscriber_skip · Resource event_subscriber_skips

  • GET /api/v1/event_subscriber_skips
  • GET /api/v1/event_subscriber_skips/{id}
ColumnTypeNullableAllowed valuesReferences
event_idstring (int64) · int8event
subscriberstring · text
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
reasonstring · text
skipped_atstring (date-time) · timestamptz

Primary key: event_id, subscriber

Events

Workflows and webhooks react to these events.

EventWhat happensPayload
platform.delivery_recordedA webhook delivery attempt finished.webhook_id, success, response_status
platform.history_purgedDelivery history and expired idempotency keys were swept.days, removed
platform.job_cancelledA queued job was cancelled.job_id
platform.job_enqueuedWork was put on the queue.job_id, type
platform.job_retriedA failed job was put back on the queue.job_id
platform.key_createdAn API key was issued.key_id, prefix
platform.key_renamedAn API key was renamed.key_id, name
platform.key_revokedAn API key was revoked.key_id, prefix
platform.test_delivery_queuedA test or replayed delivery was put on the queue.webhook_id, job_id, replay_of
platform.webhook_createdA webhook endpoint was registered.webhook_id, direction
platform.webhook_deletedA webhook endpoint was removed.webhook_id
platform.webhook_disabledA webhook endpoint was switched off.webhook_id, reason
platform.webhook_enabledA webhook endpoint was switched back on.webhook_id
platform.webhook_receivedAn inbound webhook was accepted.webhook_id, path, name, body
platform.webhook_secret_rotatedA webhook signing secret was replaced; the old one keeps working for the overlap window.webhook_id, overlap_until
platform.webhook_updatedA webhook endpoint’s address, events or limits changed.webhook_id
Was this page helpful?