curl --request POST \
--url 'https://api.noresponse.org/v1/accounts/acct_7f3a9c/outcomes' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: account-acct_7f3a9c' \
--data '{
"outcome": "unknown",
"observed_at": "2026-01-01T00:00:00Z",
"external_ref": "case_123",
"supersedes": "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM"
}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.accounts.recordOutcome({
accountId: "acct_7f3a9c",
idempotencyKey: "account-acct_7f3a9c",
body: {
outcome: "unknown",
observedAt: "2026-01-01T00:00:00Z",
externalRef: "case_123",
supersedes: "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
},
});
console.log(result);
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.accounts.record_outcome(account_id="acct_7f3a9c", idempotency_key="account-acct_7f3a9c", outcome="unknown", observed_at="2026-01-01T00:00:00Z", external_ref="case_123", supersedes="out_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
# Handle response
print(res)
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v12"
"github.com/noresponsehq/go/v12/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Accounts.RecordOutcome(ctx, "acct_7f3a9c", "account-acct_7f3a9c", components.AccountOutcomeRequest{
Outcome: components.OutcomeUnknown,
ObservedAt: noresponse.Pointer("2026-01-01T00:00:00Z"),
ExternalRef: noresponse.Pointer("case_123"),
Supersedes: noresponse.Pointer("out_01JA2Z8K6Q4V7W9XBCDEFGHJKM"),
})
if err != nil {
log.Fatal(err)
}
if res != nil {
// handle response
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.RecordAccountOutcomeResponse;
import org.noresponse.models.shared.AccountOutcomeRequest;
import org.noresponse.models.shared.Outcome;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
RecordAccountOutcomeResponse res = sdk.accounts().recordOutcome()
.accountId("acct_7f3a9c")
.idempotencyKey("account-acct_7f3a9c")
.body(AccountOutcomeRequest.builder()
.outcome(Outcome.UNKNOWN)
.observedAt("2026-01-01T00:00:00Z")
.externalRef("case_123")
.supersedes("out_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
.build())
.call();
if (res.accountOutcome().isPresent()) {
System.out.println(res.accountOutcome().get());
}
}
}
using NoResponse;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
var res = await sdk.Accounts.RecordOutcomeAsync(
accountId: "acct_7f3a9c",
body: new AccountOutcomeRequest() {
Outcome = Outcome.Unknown,
ObservedAt = "2026-01-01T00:00:00Z",
ExternalRef = "case_123",
Supersedes = "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
},
idempotencyKey: "account-acct_7f3a9c"
);
// handle response
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$body = new Shared\AccountOutcomeRequest(
outcome: Shared\Outcome::Unknown,
observedAt: '2026-01-01T00:00:00Z',
externalRef: 'case_123',
supersedes: 'out_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
);
$response = $sdk->accounts->recordOutcome(
accountId: 'acct_7f3a9c',
body: $body,
idempotencyKey: 'account-acct_7f3a9c'
);
$result = $response->result;
// handle response
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
res = s.accounts.record_outcome(account_id: 'acct_7f3a9c', body: Models::Shared::AccountOutcomeRequest.new(
outcome: Models::Shared::Outcome::UNKNOWN,
observed_at: '2026-01-01T00:00:00Z',
external_ref: 'case_123',
supersedes: 'out_01JA2Z8K6Q4V7W9XBCDEFGHJKM'
), idempotency_key: 'account-acct_7f3a9c')
unless res.nil?
# handle response
end
{
"id": "<string>",
"account_id": "<string>",
"outcome": "confirmed_abuse",
"observed_at": "2023-11-07T05:31:56Z",
"received_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"actor": {
"type": "api_key",
"key_id": "<string>",
"external_user_id": "<string>",
"console_credential_id": "<string>",
"principal_id": "<string>"
},
"risk_version_before": 2,
"risk_version": 2,
"supersedes": "<string>",
"external_ref": "<string>",
"effective_outcome_id": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/idempotency-key-reused",
"title": "Idempotency key reused",
"status": 409,
"detail": "This Idempotency-Key was used with a different request body.",
"code": "idempotency_key_reused",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}Record or correct an account outcome
Record a factual report, not an enforcement action. A known outcome replaces the effective report. unknown alone records uncertainty without changing it; unknown with supersedes explicitly retracts it. supersedes must name the current effective report or the request answers 409 outcome_conflict. Reports remain append-only. Idempotency-Key is required. observed_at defaults to receipt time and cannot be over five minutes ahead.
curl --request POST \
--url 'https://api.noresponse.org/v1/accounts/acct_7f3a9c/outcomes' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: account-acct_7f3a9c' \
--data '{
"outcome": "unknown",
"observed_at": "2026-01-01T00:00:00Z",
"external_ref": "case_123",
"supersedes": "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM"
}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.accounts.recordOutcome({
accountId: "acct_7f3a9c",
idempotencyKey: "account-acct_7f3a9c",
body: {
outcome: "unknown",
observedAt: "2026-01-01T00:00:00Z",
externalRef: "case_123",
supersedes: "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
},
});
console.log(result);
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.accounts.record_outcome(account_id="acct_7f3a9c", idempotency_key="account-acct_7f3a9c", outcome="unknown", observed_at="2026-01-01T00:00:00Z", external_ref="case_123", supersedes="out_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
# Handle response
print(res)
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v12"
"github.com/noresponsehq/go/v12/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Accounts.RecordOutcome(ctx, "acct_7f3a9c", "account-acct_7f3a9c", components.AccountOutcomeRequest{
Outcome: components.OutcomeUnknown,
ObservedAt: noresponse.Pointer("2026-01-01T00:00:00Z"),
ExternalRef: noresponse.Pointer("case_123"),
Supersedes: noresponse.Pointer("out_01JA2Z8K6Q4V7W9XBCDEFGHJKM"),
})
if err != nil {
log.Fatal(err)
}
if res != nil {
// handle response
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.RecordAccountOutcomeResponse;
import org.noresponse.models.shared.AccountOutcomeRequest;
import org.noresponse.models.shared.Outcome;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
RecordAccountOutcomeResponse res = sdk.accounts().recordOutcome()
.accountId("acct_7f3a9c")
.idempotencyKey("account-acct_7f3a9c")
.body(AccountOutcomeRequest.builder()
.outcome(Outcome.UNKNOWN)
.observedAt("2026-01-01T00:00:00Z")
.externalRef("case_123")
.supersedes("out_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
.build())
.call();
if (res.accountOutcome().isPresent()) {
System.out.println(res.accountOutcome().get());
}
}
}
using NoResponse;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
var res = await sdk.Accounts.RecordOutcomeAsync(
accountId: "acct_7f3a9c",
body: new AccountOutcomeRequest() {
Outcome = Outcome.Unknown,
ObservedAt = "2026-01-01T00:00:00Z",
ExternalRef = "case_123",
Supersedes = "out_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
},
idempotencyKey: "account-acct_7f3a9c"
);
// handle response
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$body = new Shared\AccountOutcomeRequest(
outcome: Shared\Outcome::Unknown,
observedAt: '2026-01-01T00:00:00Z',
externalRef: 'case_123',
supersedes: 'out_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
);
$response = $sdk->accounts->recordOutcome(
accountId: 'acct_7f3a9c',
body: $body,
idempotencyKey: 'account-acct_7f3a9c'
);
$result = $response->result;
// handle response
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
res = s.accounts.record_outcome(account_id: 'acct_7f3a9c', body: Models::Shared::AccountOutcomeRequest.new(
outcome: Models::Shared::Outcome::UNKNOWN,
observed_at: '2026-01-01T00:00:00Z',
external_ref: 'case_123',
supersedes: 'out_01JA2Z8K6Q4V7W9XBCDEFGHJKM'
), idempotency_key: 'account-acct_7f3a9c')
unless res.nil?
# handle response
end
{
"id": "<string>",
"account_id": "<string>",
"outcome": "confirmed_abuse",
"observed_at": "2023-11-07T05:31:56Z",
"received_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"actor": {
"type": "api_key",
"key_id": "<string>",
"external_user_id": "<string>",
"console_credential_id": "<string>",
"principal_id": "<string>"
},
"risk_version_before": 2,
"risk_version": 2,
"supersedes": "<string>",
"external_ref": "<string>",
"effective_outcome_id": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/idempotency-key-reused",
"title": "Idempotency key reused",
"status": 409,
"detail": "This Idempotency-Key was used with a different request body.",
"code": "idempotency_key_reused",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}Authorizations
Your API key, sent as Authorization: Bearer <key>. A key is nrk_live_ or nrk_test_, a 26-character key id, _ and a 43-character secret. Account, audit and usage data stay within the key's environment. Dedicated team scopes apply across the workspace.
assess creates and reads assessments, records outcomes and reports key usage. investigate reads accounts, assessment history and request diagnostics without export or enforcement access. The legacy history scope also permits account exports, submitted identifiers and enforcement reports. delete permits account and assessment deletion.
evidence or detailed adds detailed merged evidence and submitted identifiers where the operation permits them. Neither grants access to the underlying resource alone. exports permits exports with the underlying account or audit scope. audit reads audit events and usage reads usage. audit_manage manages audit streams and retention, and includes audit-read and export authority.
webhooks manages webhook endpoints. integrations manages hosted auth-provider integrations. management manages keys, settings, lists, reviews and policy evaluations in the key's environment. New keys cannot exceed the issuer's effective permissions.
settings reads configuration, previews policy and list changes, runs evaluations and changes retention. Publishing decision policy or changing lists requires settings and policy_publish together, or the legacy management scope.
groups creates and reads groups, adds people, starts and cancels screenings and records decisions on people, in the key's environment.
members reads the workspace directory. members_manage also administers non-owner members and invitations. These scopes require a live key issued by a current owner with access to both environments. They grant access across the workspace. management does not grant team access. API keys cannot change owners or accept invitations.
A missing, unknown, revoked or expired key answers 401. A valid key without a required scope answers 403.
Headers
Path Parameters
The account_id the workspace sends with its assessments, as one path segment (percent-encode '|' and ':' if the client requires it). A value that does not match the account_id shape answers 400 invalid_request. The provider's own opaque identifier for the account being checked, scoped to the calling workspace. It must be provider-opaque and must not contain a direct identifier (email, phone, name, national id): that is a provider obligation the schema can only partly check. '|' is accepted so an Auth0 user id such as 'auth0|64abc' passes unchanged; '@', '+', '$' and whitespace are refused by the pattern, as is an exact-shape JWT; a hex digest such as a SHA-256 is allowed, because hashing an internal id is a common pseudonymous scheme. A value such as '07700900123' or 'jane.doe.gmail.com' cannot be told apart from an opaque id. It travels in bodies, and in a URL only as the path segment of GET /v1/accounts/{account_id}, its /assessments and its /links. An assessment requested by a provider hook at pre_registration, which has no account yet, carries the server-issued account_id pre: followed by its assessment_id.
1 - 128^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$Body
Record a factual report, not an enforcement action. A known outcome replaces the effective report. unknown alone records uncertainty without changing it; unknown with supersedes explicitly retracts it. supersedes must name the current effective report or the request answers 409 outcome_conflict. Reports remain append-only. Idempotency-Key is required. observed_at defaults to receipt time and cannot be over five minutes ahead.
What the provider later learned about the assessed account. confirmed_abuse, account_takeover and chargeback report abuse; false_positive and legitimate withdraw an earlier abuse report of this workspace for the assessment; unknown is recorded only. Outcomes are append-only and the latest one recorded for an assessment wins.
confirmed_abuse, account_takeover, chargeback, false_positive, legitimate, unknown Response
Record or correct an account outcome. The retained snapshot; no current decision is substituted for historical evidence.
Immutable acceptance receipt. risk_version is the account version after this report committed, not the version when a retry reads it. effective_outcome_id names the effective head at that write. The effective expiration may shorten under retention changes. A legitimate report or correction removes only the account-feedback contribution, not unrelated risk.
The provider's own opaque identifier for the account being checked, scoped to the calling workspace. It must be provider-opaque and must not contain a direct identifier (email, phone, name, national id): that is a provider obligation the schema can only partly check. '|' is accepted so an Auth0 user id such as 'auth0|64abc' passes unchanged; '@', '+', '$' and whitespace are refused by the pattern, as is an exact-shape JWT; a hex digest such as a SHA-256 is allowed, because hashing an internal id is a common pseudonymous scheme. A value such as '07700900123' or 'jane.doe.gmail.com' cannot be told apart from an opaque id. It travels in bodies, and in a URL only as the path segment of GET /v1/accounts/{account_id}, its /assessments and its /links. An assessment requested by a provider hook at pre_registration, which has no account yet, carries the server-issued account_id pre: followed by its assessment_id.
1 - 128^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$What the provider later learned about the assessed account. confirmed_abuse, account_takeover and chargeback report abuse; false_positive and legitimate withdraw an earlier abuse report of this workspace for the assessment; unknown is recorded only. Outcomes are append-only and the latest one recorded for an assessment wins.
confirmed_abuse, account_takeover, chargeback, false_positive, legitimate, unknown