GoRunner docs
Search or askSearch⌘K

Make a login code

POST/api/embed/v1/login-codes

Makes a one-time login code for a person, creating the person, account and workspace if they don’t exist.

Needs a partner key: Authorization: Bearer gre_…, from Platform › Partner keys. Call it from your server only.

Embed · Self-hosted with an Embed license

Parameters

Body

userRequired · object

The person: your id (1 to 255 bytes), their name (up to 200 characters) and, if you like, email. The email is for contact only, never who they are.

accountRequired · object

The account: your id and its name.

workspaceOptional · object

A workspace: your id, and its name the first time. Left out: the account’s default workspace.

roleRequired · string

viewer, operator or editor.

turnOffOptional · array of strings

Switch IDs to turn off for this login only.

The code

Hand code to your page, which gives it to the frame. It works once, for 60 seconds. Never log it. See Login codes and sessions.

A suspended account still gets a code: its people can look, read only. A changed role ends the person’s older sessions in that workspace, which come back at the new role.

It takes no Idempotency-Key: an unused code simply runs out. One person of one account gets 20 codes a minute (EMBED_PERSON_RATE_LIMIT), so throttle your own login route per person too.

Responses

  • 201Created

    The code, and what was found or made.

  • A field isn’t valid. details.field names it.

  • The account is new, and the license’s organization limit is reached. Nothing is made.

  • A workspace would be made (a new account’s default one, or a new workspace.id), and the license’s workspace limit is reached. Nothing is made.

  • The account is deleted. Restore it first, within 30 days.

  • 409BUSY

    Something else held what this call needs, and it gave up waiting. Nothing changed. Try again.

  • Your key’s, the account’s or this person’s login codes this minute are used up. X-RateLimit-Scope says which; Retry-After says when.

  • Something failed on the installation’s side. Try again.

Any call can also answer: 401 UNAUTHORIZED · 403 EMBED_NOT_LICENSED · 403 IP_NOT_ALLOWED · 413 PAYLOAD_TOO_LARGE · 415 INVALID_CONTENT_TYPE · 503 BUSY. See Errors.

Request

GORUNNER="https://automations.example.com"
GORUNNER_EMBED_KEY="YOUR_PARTNER_KEY"  # gre_…

curl -X POST "$GORUNNER/api/embed/v1/login-codes" \
  -H "Authorization: Bearer $GORUNNER_EMBED_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "id": "ada-123",
      "name": "Ada Lovelace"
    },
    "account": {
      "id": "acct-bakery",
      "name": "Bakery Ltd"
    },
    "role": "editor"
  }'

Response · 201 Created

json
{
  "data": {
    "code": "grl_…",
    "expiresAt": "2026-10-25T09:01:00Z",
    "expiresIn": 60,
    "account": {
      "id": "acct-bakery",
      "status": "active",
      "created": false
    },
    "workspace": {
      "id": null,
      "default": true,
      "created": false
    },
    "user": {
      "id": "ada-123",
      "created": true
    },
    "role": "editor"
  }
}
Every field

Body

userRequired · object
idRequired · string
nameRequired · string
emailOptional · string or null
accountRequired · object
idRequired · string
nameRequired · string
workspaceOptional · object

Omitted = the account’s default workspace. name is needed the first time.

idRequired · string
nameOptional · string
roleRequired · string

One of viewer, operator, editor.

turnOffOptional · array of strings

Switches off for this login only. An id that does not exist is 400 VALIDATION_ERROR (details.unknown).

Response · 201 Created

dataobject
codestring

grl_… — single use, 60 seconds.

expiresAttime
expiresIninteger
accountobject
idstring
statusstring

One of active, suspended.

createdboolean
workspaceobject
idstring or null
defaultboolean
createdboolean
userobject
idstring
createdboolean
rolestring

One of viewer, operator, editor.