> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noresponse.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Accounts

> Get the one current risk of an account with a decision for each flow, page through its assessments, and delete the account.

An account is the `account_id` that you send with your assessments. It holds one current risk: the risk of its latest assessment with a decision. Its assessments are its history. Every assessment updates its account. So when an assessment completes, the account carries its risk.

Your account creation gate can issue an API key to the account. When that key has use from many IP addresses or countries, the risk of the account also carries the `shared_api_key` reason. See [Report key usage](https://docs.noresponse.org/guides/key-usage.md).

Every assessment answer carries the same object as its `account`. So the call that you assess with already tells you the decision for the account. Get the account when a later request needs the risk that you already paid for. Examples are a login, a purchase or an admin review, long after the account creation.

When a user asks you to delete their data, [delete the account](#delete-an-account). Every route is in the [interactive reference](https://docs.noresponse.org/api-reference.md).

## Get an account

`GET /v1/accounts/{account_id}` needs the `history` scope. It only reads, and a retry is safe.

```ts title="TypeScript" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
try {
  const account = await nr.accounts.get("usr_8f2k1");
  console.log(account.risk.score, account.risk.decision, account.decisionsByFlow.purchase);
} catch (error) {
  if (!(error instanceof NotFoundError)) throw error;
  // No decided assessment for this account yet: assess it first.
}
```

```python title="Python" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
from noresponse import NotFoundError

try:
    account = client.accounts.get("usr_8f2k1")
    print(account.risk.score, account.risk.decision, account.decisions_by_flow.purchase)
except NotFoundError:
    pass  # No decided assessment for this account yet: assess it first.
```

```go title="Go" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
res, err := client.Accounts.Get(ctx, "usr_8f2k1")
var notFound *apierrors.NotFoundError
switch {
case errors.As(err, &notFound):
	// No decided assessment for this account yet: assess it first.
case err != nil:
	return err
default:
	account := res.Result
	fmt.Println(account.Risk.Score, account.Risk.Decision, account.DecisionsByFlow.Purchase)
}
```

```bash title="cURL" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl https://api.noresponse.org/v1/accounts/usr_8f2k1 \
  -H "Authorization: Bearer $NORESPONSE_API_KEY"
```

### Parameters

**account\_id** `string` *required*

The account, in the same shape as on create. It has 1 to 128 characters. The first is a letter or a digit. The others are letters, digits, `.`, `_`, `:`, `|` and `-`.

Percent-encode `:` and `|` if your HTTP client needs it.

The route takes no query parameters.

### Response

`200 OK` with the account.

**schema\_version** `string`

`"1"`.

**id** `string`

The `account_id` that you asked about.

**risk** `object`

**properties**

**score** `integer`

0 (safe) to 100 (risky). It is the `detail.risk.score` of the assessment that the risk comes from.

**decision** `string`

`allow`, `step_up`, `review` or `block`. Your application applies it.

* It is `block` when the score reached your block threshold. In other cases, it is the recommendation of that assessment.
* On this route, it is the decision for the flow of the assessment that the risk comes from.
* Inside an assessment, it is the decision for the flow of that assessment.

**reasons** `object[]`

The reasons for the score, as on the assessment. See [Reason codes](https://docs.noresponse.org/reference/reason-codes.md).

**decisions\_by\_flow** `object`

The decision for `account_creation`, `login` and `purchase`, each under the thresholds of that flow. A flow that you did not set uses your account creation thresholds.

**assessment\_id** `string`

The assessment that the current risk comes from. To get its `detail`, call `GET /v1/assessments/{assessment_id}`.

**updated\_at** `string`

When NoResponse wrote the latest version of that assessment.

```json title="Account" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
{
  "schema_version": "1",
  "id": "usr_8f2k1",
  "risk": {
    "score": 35,
    "decision": "step_up",
    "reasons": [
      { "code": "new_email", "weight": 20, "identifier": "email" },
      { "code": "proxy_ip", "weight": 15, "identifier": "ip" }
    ]
  },
  "decisions_by_flow": { "account_creation": "step_up", "login": "step_up", "purchase": "step_up" },
  "assessment_id": "asm_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
  "updated_at": "2026-10-14T09:00:00.412Z"
}
```

The current risk comes from the latest assessment of the account whose `status` is `complete` or `partial`, newest by `created_at`. A `pending` assessment does not replace it until it settles. NoResponse scores the risk exactly as `GET /v1/assessments/{assessment_id}` scores that assessment. So the two always agree.

When the decision for any flow changes, NoResponse sends an [`account.risk_changed`](https://docs.noresponse.org/guides/webhooks#account-risk_changed) event with this object and the decisions it replaced. You do not need to poll this route to see the change.

| Status | Code | When |
| - | - | - |
| 400 | `invalid_request` | `account_id` does not match its shape. |
| 401 | `unauthorized` | No key, or a malformed, unknown, revoked or expired key. |
| 403 | `workspace_forbidden` | The key does not have `history`. |
| 404 | `not_found` | The account has no unexpired assessment with a decision. NoResponse never assessed it, its only assessment is still `pending`, or every assessment expired. An account of another workspace gets the same answer. |
| 429 | `rate_limited` | Retry after `Retry-After`. |
| 503 | `service_unavailable` | Retry after `Retry-After`. |

## List the assessments of an account

`GET /v1/accounts/{account_id}/assessments` answers the same pages as [`POST /v1/assessments/query`](https://docs.noresponse.org/reference/get-and-query#query-the-history-of-an-account), for the account in the path. The pages hold its unexpired assessments, newest first. Each is at its latest `assessment_version`, in the shape of the `detail` of an assessment.

The route needs the `history` scope. It only reads, and a retry is safe.

```ts title="TypeScript" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
const page = await nr.accounts.listAssessments("usr_8f2k1", { limit: 20 });
for await (const assessment of page) {
  console.log(assessment.assessmentId, assessment.status);
}
```

```python title="Python" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
for assessment in client.accounts.list_assessments("usr_8f2k1", limit=20):
    print(assessment.assessment_id, assessment.status)
```

```go title="Go" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
res, err := client.Accounts.ListAssessments(ctx, "usr_8f2k1", noresponse.Pointer(int64(20)), nil, nil)
for res != nil && err == nil {
	for _, assessment := range res.Result.Items {
		fmt.Println(assessment.AssessmentID, assessment.Status)
	}
	res, err = res.Next()
}
if err != nil {
	return err
}
```

```bash title="cURL" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl "https://api.noresponse.org/v1/accounts/usr_8f2k1/assessments?limit=20" \
  -H "Authorization: Bearer $NORESPONSE_API_KEY"
```

**account\_id** `string` *required*

As above.

**limit** `integer` (default: 20)

1 to 50 items for each page.

**cursor** `string`

The `next_cursor` of the previous page, unchanged.

**response\_mode** `string` (default: standard)

`standard` or `detailed`. `detailed` needs the `detailed` scope and the `history` scope.

The response is the [history page](https://docs.noresponse.org/reference/get-and-query.md#response-2). An account with no assessments answers 200 with empty `items`.

* A cursor that is changed, foreign or expired answers 400 `invalid_cursor`.
* A malformed `account_id` answers 400 `invalid_request`.
* An unknown, repeated or out-of-range query parameter answers 400 `invalid_request`.

> [!WARNING]
>
> This route puts the `account_id` in the URL, where proxies and access logs can record it. `POST /v1/assessments/query` carries it in the body. Use the route that fits your logging.

## Delete an account

`DELETE /v1/accounts/{account_id}` deletes one of your accounts, for example when your user asks you to delete their data. It needs the `history` scope.

The call acts only in the environment of your key. A delete with a test key does not change the live account, and the other way round. To delete one assessment and keep the rest of the account, see [Delete an assessment](https://docs.noresponse.org/reference/get-and-query.md#delete-an-assessment).

```ts title="TypeScript" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
const erased = await nr.accounts.delete("usr_8f2k1");
console.log(erased.assessmentsDeleted, erased.deletedAt);
```

```python title="Python" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
erased = client.accounts.delete("usr_8f2k1")
print(erased.assessments_deleted, erased.deleted_at)
```

```go title="Go" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
res, err := client.Accounts.Delete(ctx, "usr_8f2k1")
if err != nil {
	return err
}
fmt.Println(res.Result.AssessmentsDeleted, res.Result.DeletedAt)
```

```bash title="cURL" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl https://api.noresponse.org/v1/accounts/usr_8f2k1 \
  -X DELETE \
  -H "Authorization: Bearer $NORESPONSE_API_KEY"
```

The path takes the same `account_id` as [Get an account](#parameters). The route takes no query parameters.

### What goes

> [!CAUTION]
>
> In one step, NoResponse deletes every assessment of the account, with all its versions, its evidence and the outcomes that you reported on it. You cannot undo the delete.

* An abuse outcome that you reported on one of those assessments stops counting toward other assessments at once.
* NoResponse stops an assessment of the account that still ran when the call arrived.
* NoResponse refuses a create request for the account that started before the call.

After the delete, you cannot read anything of the account:

* `GET /v1/accounts/{account_id}` answers 404 `not_found`.
* `GET /v1/assessments/{assessment_id}` answers 404 for each deleted assessment. An outcome report on one of them also answers 404.
* The history of the account is an empty page on both history routes.

NoResponse does not block the `account_id` itself. A new assessment for it after the delete starts a new account with a new history.

### Response

`200 OK` with what the call deleted.

**schema\_version** `string`

`"1"`.

**id** `string`

The `account_id` that you deleted.

**deleted** `boolean`

Always `true`.

**assessments\_deleted** `integer`

The number of assessments that this call deleted.

**deleted\_at** `string`

When the delete took effect.

```json title="Delete response" theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
{
  "schema_version": "1",
  "id": "usr_8f2k1",
  "deleted": true,
  "assessments_deleted": 3,
  "deleted_at": "2026-10-23T09:00:00.000Z"
}
```

The call is idempotent, and a retry is safe. A repeat, or an account with nothing to delete, answers `200` with `assessments_deleted: 0`.

### The account.deleted event

When the call deleted at least one assessment, NoResponse sends one [`account.deleted`](https://docs.noresponse.org/guides/webhooks#account-deleted) webhook event to your verified endpoints in the same environment. Every system that holds data about the account can then delete it too.

Delete only what comes from assessments created at or before its `deleted_at`. NoResponse can already have assessed the account again. A repeat that deleted nothing sends no event.

| Status | Code | When |
| - | - | - |
| 400 | `invalid_request` | `account_id` does not match its shape, or the request has a query parameter. |
| 401 | `unauthorized` | No key, or a malformed, unknown, revoked or expired key. |
| 403 | `workspace_forbidden` | The key does not have `history`. |
| 429 | `rate_limited` | Retry after `Retry-After`. |
| 503 | `service_unavailable` | Retry after `Retry-After`. A retry is safe. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.