# Restore an account

**POST** `/api/embed/v1/accounts/{accountId}/restore`

Brings back a deleted account, within 30 days, in the state it had.

Needs a partner key: `Authorization: Bearer gre_…`, from [Platform › Partner keys](https://docs.gorunner.io/embed/platform-screens#partner-keys). Call it from your server only.

Embed · Self-hosted with an Embed license

## Parameters

### Path

- `accountId` · Required · string: Your ID for the customer’s account: 1 to 255 bytes of UTF-8, case-sensitive. URL-encode it: it may contain `/`.

### Headers

- `Idempotency-Key` · Optional · string: Up to 255 characters. The same request with the same key within 24 hours answers the first result again, with `Idempotency-Replayed: true`.

## Your license

A restored account counts against the license’s organization limit again.

## Responses

- 200 OK

  The account.

- 400 `VALIDATION_ERROR`

  The account ID isn’t allowed as written. `details.field` names it.

- 403 `ORG_LIMIT`

  Restoring it would pass the license’s organization limit.

- 404 `NOT_FOUND`

  No such account, or it was already removed for good.

- 409 `ACCOUNT_NOT_DELETED`

  The account isn’t deleted.

- 409 `RESTORE_EXPIRED`

  The 30 days are over. It can’t be restored.

- 409 `CONFLICT`

  A request with this `Idempotency-Key` is still running. Retry shortly.

- 422 `VALIDATION_ERROR`

  This `Idempotency-Key` was already used with a different request.

- 500 `INTERNAL_ERROR`

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

Any call can also answer: [`401 UNAUTHORIZED`](https://docs.gorunner.io/errors#UNAUTHORIZED) · [`403 EMBED_NOT_LICENSED`](https://docs.gorunner.io/errors#EMBED_NOT_LICENSED) · [`403 IP_NOT_ALLOWED`](https://docs.gorunner.io/errors#IP_NOT_ALLOWED) · [`413 PAYLOAD_TOO_LARGE`](https://docs.gorunner.io/errors#PAYLOAD_TOO_LARGE) · [`415 INVALID_CONTENT_TYPE`](https://docs.gorunner.io/errors#INVALID_CONTENT_TYPE) · [`429 RATE_LIMITED`](https://docs.gorunner.io/errors#RATE_LIMITED) · [`503 BUSY`](https://docs.gorunner.io/errors#BUSY). See [Errors](https://docs.gorunner.io/embed/api#errors).

Request

**curl**

```bash
GORUNNER="https://automations.example.com"
GORUNNER_EMBED_KEY="YOUR_PARTNER_KEY"  # gre_…
ACCOUNT_ID="acct-bakery"

URL="$GORUNNER/api/embed/v1/accounts/$ACCOUNT_ID/"
URL="${URL}restore"
curl -X POST "$URL" \
  -H "Authorization: Bearer $GORUNNER_EMBED_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
```

**JavaScript**

```js
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}/restore`,
  {
    method: "POST",
    headers: {
        Authorization: `Bearer ${KEY}`,
        "Idempotency-Key": crypto.randomUUID(),
      },
  },
);
const { data } = await res.json();
```

**Python**

```python
import os, uuid, 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.post(
    f"{GORUNNER}/api/embed/v1/accounts/"
    f"{ACCOUNT_ID}/restore",
    headers={
        "Authorization": f"Bearer {KEY}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
)
data = res.json()["data"]
```

Response · 200 OK

```json
{
  "data": {
    "id": "acct-bakery",
    "name": "Bakery Ltd",
    "status": "active",
    "turnOff": [],
    "pieces": null,
    "assistant": {
      "monthlyTokens": null
    },
    "limits": {
      "concurrentRuns": null
    },
    "workspaces": 2,
    "members": 5,
    "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**

It takes no body.

### Response · 200 OK

- `data` · object
  - `id` · string
  - `name` · string
  - `status` · string: One of `active`, `suspended`, `deleted`.
  - `turnOff` · array of strings
  - `pieces` · array of strings or null: Null inherits the installation’s list.
  - `assistant` · object
    - `monthlyTokens` · integer or null
  - `limits` · object
    - `concurrentRuns` · integer or null: How 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.
  - `workspaces` · integer
  - `members` · integer: Distinct people with access.
  - `suspendedAt` · time or null
  - `suspendedReason` · string or null
  - `deletedAt` · time or null
  - `purgeAfter` · time or null
  - `createdAt` · time
  - `updatedAt` · time
  - `organizationId` · UUID: The installation’s own id, for support.
  - `aiSignIn` · object
    - `address` · URL or null: This 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.signInFrom` says which).
  - `mcp` · object or null: Only 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.address` or the installation’s), they are the account’s own addresses and `signIn` is true; otherwise the plain addresses tokens use.
    - `build` · URL or null: The address that builds and manages workflows; null while MCP building (`mcpBuild`) is off.
    - `tools` · URL: The address that calls the published workflows.
    - `signIn` · boolean: Whether an AI app can connect by signing in: through the account’s own `aiSignIn.address` while its website is allowed, or the installation’s AI app sign-in address.
    - `signInFrom` · string or null: Whose address a sign-in uses: `account` (its own `aiSignIn.address`) or `installation`; null when `signIn` is false. `installation` while `aiSignIn.address` is set means its website is no longer allowed for the account. One of `account`, `installation`, `null`.

Related: [Delete an account](https://docs.gorunner.io/embed/api/accounts/delete-account)

Source: https://docs.gorunner.io/embed/api/accounts/restore-account
