Create or update an account
This page needs your own installation with an Embed license.
PUT/
Creates an account by your ID, or updates it. A field you leave out is left as it is.
Needs a partner key: Authorization: Bearer gre_…, from Platform › Partner keys. Call it from your server only.
Parameters
Path
accountIdRequired · stringYour ID for the customer’s account: 1 to 255 bytes of UTF-8, case-sensitive. URL-encode it: it may contain
/.
Body
nameOptional · stringUp to 200 characters. Needed to create.
turnOffOptional · array of strings or nullSwitch IDs turned off for the whole account. Replaces the list;
nullclears it.piecesOptional · array of strings or nullThe apps the account may use, within the installation’s list.
null: the installation’s list.[]: only branch and loop. Unknown IDs are refused by name.limits.concurrentRunsOptional · integer or nullRuns at once: a number, 0 for no limit,
nullfor the installation’s default. Runs over it wait in line.
What are the rarely used parameters?
assistant.monthlyTokensOptional · integer or nullKeel’s monthly allowance.
null: the installation’s default.aiSignInOptional · object or nullThe account’s own AI app sign-in address,
{"address": "https://…"}.nullclears it. Its website must already be allowed for this account. Needs v2026.10.24 or later: an older installation ignores it, so check that the answer hasaiSignIn. See Let customers sign in AI apps.
Safe to send again
It is keyed by your ID, so the same request twice leaves the same account. Every field is checked before anything is written.
To set aiSignIn on a new account: create it with a name, allow its website, then set the address. A later change to the address doesn’t affect AI apps already connected.
Responses
- 200OK
Updated.
- 201Created
Created, with its default workspace.
A field isn’t valid, such as an unknown app in
pieces(details.unknown) or one outside the installation’s list (details.notAllowed). Nothing is written.- 403
ORG_LIMITCreating the account would pass the license’s organization limit. Nothing is made.
Creating the account’s default workspace would pass the license’s workspace limit. Nothing is made.
The account is deleted. Restore it first, within 30 days. Even clearing
aiSignInis refused.- 409
BUSYSomething else held what this call needs, and it gave up waiting. Nothing changed. Try again.
aiSignIn.addressisn’t on a website allowed for this account (details.origin). Add the website first. Nothing is written.Something failed on the installation’s side. Try again.
The installation’s app list couldn’t be read. Nothing was written.
Any call can also answer: 401 UNAUTHORIZED · 403 EMBED_NOT_LICENSED · 403 IP_NOT_ALLOWED · 413 PAYLOAD_TOO_LARGE · 415 INVALID_CONTENT_TYPE · 429 RATE_LIMITED · 503 BUSY. See Errors.
Request
GORUNNER="https://automations.example.com"
GORUNNER_EMBED_KEY="YOUR_PARTNER_KEY" # gre_…
ACCOUNT_ID="acct-bakery"
URL="$GORUNNER/api/embed/v1/accounts/$ACCOUNT_ID"
curl -X PUT "$URL" \
-H "Authorization: Bearer $GORUNNER_EMBED_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Bakery Ltd",
"limits": {
"concurrentRuns": 5
}
}'const GORUNNER = "https://automations.example.com";
const KEY = process.env.GORUNNER_EMBED_KEY; // gre_…
const ACCOUNT_ID = encodeURIComponent("acct-bakery");
const res = await fetch(
`${GORUNNER}/api/embed/v1/accounts/` +
`${ACCOUNT_ID}`,
{
method: "PUT",
headers: {
Authorization: `Bearer ${KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Bakery Ltd",
limits: { concurrentRuns: 5 },
}),
},
);
const { data } = await res.json();import os, requests
from urllib.parse import quote
GORUNNER = "https://automations.example.com"
KEY = os.environ["GORUNNER_EMBED_KEY"] # gre_…
ACCOUNT_ID = quote("acct-bakery", safe="")
res = requests.put(
f"{GORUNNER}/api/embed/v1/accounts/"
f"{ACCOUNT_ID}",
headers={"Authorization": f"Bearer {KEY}"},
json={
"name": "Bakery Ltd",
"limits": {"concurrentRuns": 5},
},
)
data = res.json()["data"]Response · 201 Created
{
"data": {
"id": "acct-bakery",
"name": "Bakery Ltd",
"status": "active",
"turnOff": [],
"pieces": null,
"assistant": {
"monthlyTokens": null
},
"limits": {
"concurrentRuns": 5
},
"workspaces": 1,
"members": 0,
"suspendedAt": null,
"suspendedReason": null,
"deletedAt": null,
"purgeAfter": null,
"createdAt": "2026-10-20T08:00:00Z",
"updatedAt": "2026-10-25T09:00:00Z",
"organizationId": "e9d2b6f1-3a7c-4d05-b8e4-1c6f2a9d7b30",
"aiSignIn": {
"address": null
}
}
}Every field
Body
nameOptional · stringRequired to create. Left out or null: left as it is.
turnOffOptional · array of strings or nullSwitch ids off for this account, replacing the list; null or
[]clears it. An id that does not exist is 400VALIDATION_ERROR(details.unknown).piecesOptional · array of strings or nullThe account’s own app list: app ids, within the installation’s list; null inherits the installation’s. An id no app has is 400
VALIDATION_ERROR(details.fieldpieces,details.unknown), one the installation’s list leaves out the same withdetails.notAllowed— nothing is stored.assistantOptional · objectmonthlyTokensOptional · integer or nulllimitsOptional · objectconcurrentRunsOptional · integer or nullThe account’s runs at once: a number, 0 for no limit, null for the installation’s default. Left out, it is left as it is. The last change counts, from here or from Platform › Organizations.
aiSignInOptional · object or nullThis account’s own AI app sign-in address, for a partner whose people sign in on a domain of their own (a reseller’s site). Left out, it is left as it is; null,
{"address": null}or{"address": ""}clears it, and the account’s people go to the installation’s address again.{}and an address of spaces are refused (400). On a deleted account the PUT is 409ACCOUNT_DELETED, even to clear it. Changing or clearing the address never affects AI apps already connected. An older server ignores this field on an existing account: check that the answer carriesaiSignIn.addressRequired · string or nullThe page in your product where this account’s people sign in. Surrounding spaces are trimmed. The installation’s address’s rules apply, and a few more:
https, or http on
localhost,127.0.0.1or[::1];no
#fragment, no user name or password, at most 2,000 characters, not the installation’s own host;no invisible or direction-changing characters; a host name or an IP address, with no trailing dot, and a valid port;
a query without
;, where every%starts an escape, and with no parameter that starts withgr_in any letter case (gr_requestis the installation’s).A problem with the address itself is 400
VALIDATION_ERROR(details.fieldaiSignIn.address). It is stored and answered in a standard form: the host in lower case, an international name in itsxn--form, no default port. Your query parameters are kept, but may be reordered and re-encoded whengr_requestis added.Its website (scheme, host and port) must already be allowed for THIS account: one of the installation’s allowed websites (a wildcard covers subdomains at any depth, never the bare domain) or exactly one of this account’s own websites, added with
POST /accounts/{accountId}/websites(a PUT there replaces the whole list), never another account’s. Otherwise 422SIGN_IN_ADDRESS_NOT_ALLOWEDwithdetails.origin. Either way nothing is stored, not even an account this PUT would have created: create the account with aname, add its website, then set the address. If that website is removed later, the stored address is kept but not used until the website is added again.
Response · 200 OK, 201 Created
dataobjectidstringnamestringstatusstringOne of
active,suspended,deleted.turnOffarray of stringspiecesarray of strings or nullNull inherits the installation’s list.
assistantobjectmonthlyTokensinteger or nulllimitsobjectconcurrentRunsinteger or nullHow many runs this account may have executing at once. Null = the installation’s default (Platform › Settings › General), 0 = no limit. Runs over it wait in line and start in order; none is refused for it.
workspacesintegermembersintegerDistinct people with access.
suspendedAttime or nullsuspendedReasonstring or nulldeletedAttime or nullpurgeAftertime or nullcreatedAttimeupdatedAttimeorganizationIdUUIDThe installation’s own id, for support.
aiSignInobjectaddressURL or nullThis account’s own AI app sign-in address: where an AI app’s sign-in sends this account’s people instead of the installation’s address. Null: they go to the installation’s address (Platform › What customers get › Developers). It is used only while its website is still one of the installation’s allowed websites or one of this account’s own; otherwise the installation’s address is used, or, when the installation has none, no AI app can sign in to the account (
mcp.signInFromsays which).mcpobject or nullOnly on GET /accounts/{accountId}: the account’s MCP addresses as its people find them on the MCP page. Null while Tokens or MCP is off for the account, or it is deleted. While an AI app can sign in to it (AI app sign-in on, and a sign-in address to send its people to: the account’s own
aiSignIn.addressor the installation’s), they are the account’s own addresses andsignInis true; otherwise the plain addresses tokens use.buildURL or nullThe address that builds and manages workflows; null while MCP building (
mcpBuild) is off.toolsURLThe address that calls the published workflows.
signInbooleanWhether an AI app can connect by signing in: through the account’s own
aiSignIn.addresswhile its website is allowed, or the installation’s AI app sign-in address.signInFromstring or nullWhose address a sign-in uses:
account(its ownaiSignIn.address) orinstallation; null whensignInis false.installationwhileaiSignIn.addressis set means its website is no longer allowed for the account.One of
account,installation,null.