Docs
Account, keys and webhooks ›

Create api key

POST/v1/api-keys

Makes a key that may do what it is given and nothing else: a preset, or actions named. A key used to make one makes only a weaker one: no action it lacks, no sandbox or template it does not reach, no later expiry, and addresses inside its own. The key is made in the organization the caller acts in, a team or the person's own, and acts in it for good. A person signed in to the site whose account has two-factor sign-in on sends a code from the app too, as code.

RequestTypeScript
  1. import { Agental } from "agental-sdk";
  2. const agental = new Agental();
  3. const key = await agental.apiKeys.create({ name: "ci", preset: "ci" });
Answer201 Created · CreatedApiKey

No JSON body.

The key, and its secret, which is returned this once.

Headers

Authorizationrequired
Bearer key
An API key that may make this call.

Body

namerequired
string
e.g. "ci-github"
preset
"read-only" | "full-sandbox" | "ci" | "admin"
read-only: every read but secrets and mail. full-sandbox: sandbox.read, exec, file.read, file.write, agent.prompt, ssh, desktop, host, snapshot.read, snapshot.write and sandbox.stop. ci: full-sandbox, and sandbox.create, sandbox.fork, sandbox.resume and sandbox.delete-own. admin: * , everything. Send this or actions, not both. e.g. "ci"
actions
array of "sandbox.read" | "sandbox.create" | "sandbox.fork" | "sandbox.update" | "sandbox.auto-stop" | "sandbox.stop" | "sandbox.resume" | "sandbox.delete" | "sandbox.delete-own" | "exec" | "file.read" | "file.write" | "agent.prompt" | "ssh" | "desktop" | "host" | "network.write" | "secret.read" | "secret.write" | "email.read" | "email.send" | "email.manage" | "snapshot.read" | "snapshot.write" | "template.read" | "template.write" | "key.manage" | "account.read" | "account.admin" | "members.read" | "members.admin" | "*"
The actions the key may do, named. Send this or preset, not both. e.g. ["email.read","email.send"]
sandboxIds
array of string
Limits the key to these sandboxes, and to those on templateIds. It always reaches the sandboxes it makes. Every other sandbox, snapshot and route of the account answers it 404.
templateIds
array of string
Limits the key to these templates and the sandboxes on them, and to those in sandboxIds. A sandbox it makes without naming a template goes on the account's default template when that is on the list, else on the one template on the list; with several on the list and not the default, it has to name one. e.g. ["tpl_coding_agent"]
expiresAt
string
When the key stops working, and is refused with 401 key_expired. Left out, never. e.g. "2026-11-15T00:00:00Z"
allowFrom
array of string
IPv4 and IPv6 addresses and ranges the key may be used from, 100 at most: an address alone is that one computer, and a range is written as 203.0.113.0/24 or 2001:db8::/48. An IPv4 address written the IPv6 way, as ::ffff:203.0.113.7, is that IPv4 address. Empty, or left out, is anywhere. A request from any other address is refused with 403 key_address_forbidden. A sandbox reaches the API from its server's shared IPv4 address, which changes when it moves, so limit a key used inside a sandbox with sandboxIds instead. On a network with IPv6 the API sees your IPv6 address, so a list of IPv4 addresses alone refuses you there. e.g. ["203.0.113.0/24","2001:db8::/48"]
code
string
For a person signed in to the site whose account has two-factor sign-in on: the six digits the authenticator app shows now, or one of the backup codes, which is then used up. A key outlives the session that made it, so it is not made without one. A call made with an API key needs none, and its code is not read. e.g. "482913"

Returns

201 The key, and its secret, which is returned this once.

Errors and other answers

400invalid_request neither preset nor actions was sent, or both were; expiresAt is not in the future; or an entry of allowFrom is no address or range, and the message says which.
400code_required a person signed in, with two-factor sign-in on, sent no code.
400invalid_code the code is not right.
400code_used six digits from the app that were used already.
402billing_required the account is on the free plan with no card saved, where plans are required. Save one, or start a plan, in the console first; the message gives its address.
403key_action_forbidden the key used lacks key.manage.
403key_exceeds_caller the new key would be stronger than the key used to make it, and the message says how.
403not_a_member the key used is of someone no longer in the team it acts in.
404not_found a sandbox or template named is not one of the account's, or not one the key used reaches.
409name_taken another key has this name, or the name is the one kept for the seeded dev key.
429rate_limited five wrong codes from this session in a quarter of an hour, on this call or another that asks for one.

Every error answers { "error": { "code", "message" } }; a key without the action a call needs answers 403 key_action_forbidden, naming it.