Create Accountor Login
Docs

API Keys and the REST API

Part of the MountDev Ops Workspace documentation. Updated October 7, 2026

MountDev Ops Workspace documentation | Updated October 7, 2026

Your other systems can read and change your workspace through its REST API, each with an API key of its own. A key works like a person with a role: it sees and changes exactly what its access allows, with the same checks as the screens, and everything it does is written in the Activity Log with its name.

API Keys

In the workspace menu, Integrations, API Keys (owners and admins only; action core.api_keys.list):

  • Make a Key (action core.api_keys.create): a name (name it after the system that will use it), its access, and optionally the addresses it may be used from. The key is shown once, with Copy. Copy it then: it is never shown again, to anyone, because only a fingerprint of it is kept.
  • Access:
    • Every record, like an admin: sees and changes every record in every app, as an admin does.
    • By app role, like a member: a role in each app (Manager, Team member, Viewer, or one of your own roles), as a member has (Roles). Records a key adds are owned by the key, so a Team member key sees only the records it added. If a role it has is deleted later, the key keeps only the least access in that app until you choose another.
  • Allowed addresses: IP addresses or ranges, such as 203.0.113.7 or 203.0.113.0/24, one per line. A call from any other address is refused and logged. Empty means any address.
  • Each key shows the last 4 characters of the key, when it was last used and from where, and how many calls it has made.
  • Change (action core.api_keys.update): its name, access, and addresses. The key itself stays the same.
  • Revoke (action core.api_keys.revoke): the key is refused from its next call on, for good. Make a new key to replace it.

Make one key per system, so each can be revoked on its own. AI agents can never see or make API keys.

What a Key Can Never Do

A key never reaches what stays with people: people, roles, and access; Setup (apps, modules, and fields); importing and exporting; billing settings; API connections, webhooks, automations, inbound webhooks, and other keys; and the Activity Log. It can never reply to a client by email or charge money. It can run only the actions marked safe for keys: the record actions below, and the app actions AI agents may use outside Setup.

Calling the API

The API's address is your workspace's address followed by /api/v1/, shown with Copy on the API Keys tab. Send the key in the Authorization header:

Authorization: Bearer mdo_...

Bodies are JSON. Every answer is JSON: { "result": ... } when it worked, or { "error": "..." } with a plain reason. Status codes: 200 worked, 400 the request was not understood, 401 the key is missing, wrong, or revoked, 403 the key may not do that (or not from this address), 404 the address or record does not exist (a record the key may not see answers the same way), 409 someone changed the record since you read it, 413 too large (bodies up to 1 MB), 429 too many requests.

Method and addressWhat it does
GET meThe key's name and access, and your company's name
GET modulesEvery module the key can see, with its fields
GET records/<module>Records of a module, newest change first. Optional q (text to find), limit (up to 200), offset, and sort (updated or created)
POST records/<module>Add a record: { "values": { "<field>": ... } }
GET records/<module>/<id>One record, its fields, and what the key may do with it
PATCH records/<module>/<id>Change some values: { "values": { ... }, "version": 3 }. With a version, nothing is saved if the record changed since
DELETE records/<module>/<id>Delete a record (when its access allows)
GET records/<module>/<id>/historyThe record's history
GET search?q=<text>Records matching the text in every module the key can see, up to 5 from each (limit up to 20)
GET actionsEvery action the key can run, with its inputs
POST actions/<action>Run one of those actions with its input as the body

A module is named by its app and key, such as crm.contacts, crm.deals, or helpdesk.tickets; GET modules lists them. Values are checked exactly as on the screens: a value that does not fit a field is refused with the reason, and nothing is saved.

For example, to add a contact:

POST /api/v1/records/crm.contacts Authorization: Bearer mdo_... Content-Type: application/json

{ "values": { "name": "Ann Lee", "email": "ann@example.com" } }

Changes made with a key are marked API key in each record's history and in the Activity Log, and they set off your webhooks and automations like any other change.

Ask Us Anything

We’d love to hear from you!