<!-- llms.txt: https://workos.com/llms.txt -->
<!-- feedback.md: https://workos.com/docs/feedback.md -->

# Agent Registration

:::code-group{title="Example AgentRegistration"}

```json language="curl"
{
  "id": "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY",
  "agent_identity": {
    "id": "agent_identity_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "userland_user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z"
  },
  "organization_id": "org_01EHQMYV6MBK39QC5PZXHY59C3",
  "status": "verified",
  "revoked_at": null,
  "kind": "service_auth",
  "claim": {
    "id": "agent_reg_claim_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "claim_completion": {
      "id": "agent_reg_claim_attempt_01EHWNCE74X7JSDV0X3SZ3KJNY",
      "created_at": "2026-01-15T12:00:00.000Z",
      "updated_at": "2026-01-15T12:00:00.000Z",
      "expires_at": "2026-01-15T12:00:00.000Z",
      "claimed_at": "2026-01-15T12:00:00.000Z"
    },
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z",
    "expires_at": "2026-01-15T12:00:00.000Z"
  },
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Get an agent registration

Retrieve the details of an agent registration by ID. The registration is scoped to the environment of the API key used to authenticate the request.

:::code-group

```bash language="curl" title="Request" tab="1"
curl "https://api.workos.com/agents/registrations/agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY" \
  --header "Authorization: Bearer sk_example_123456789"
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.agents.get_registration(id: "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.agents.get_registration(id_="agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.Agents().GetRegistration(context.Background(), "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos->agents()->getRegistration(id: "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;

WorkOS workos = new WorkOS("sk_example_123456789");

workos.agents.getRegistration("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.Agents.GetRegistrationAsync("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```rust language="rust" title="Request" tab="1"
use workos::Client;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .agents()
        .get_registration("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "id": "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY",
  "agent_identity": {
    "id": "agent_identity_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "userland_user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z"
  },
  "organization_id": "org_01EHQMYV6MBK39QC5PZXHY59C3",
  "status": "verified",
  "revoked_at": null,
  "kind": "service_auth",
  "claim": {
    "id": "agent_reg_claim_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "claim_completion": {
      "id": "agent_reg_claim_attempt_01EHWNCE74X7JSDV0X3SZ3KJNY",
      "created_at": "2026-01-15T12:00:00.000Z",
      "updated_at": "2026-01-15T12:00:00.000Z",
      "expires_at": "2026-01-15T12:00:00.000Z",
      "claimed_at": "2026-01-15T12:00:00.000Z"
    },
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z",
    "expires_at": "2026-01-15T12:00:00.000Z"
  },
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Link a claim attempt to an external user

Link an external user to a claim attempt and retrieve the code needed for the agent to complete the claim. The user is looked up by external ID; if no user exists, one is created. When the user belongs to multiple organizations, an explicit organization must be provided.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request PATCH \
  --url "https://api.workos.com/agents/claims/attempts" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "type": "link_external_user",
        "claim_attempt_token": "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
        "user": {
            "email": "alice@example.com",
            "external_id": "user_abc123"
        }
    }
BODY
```

```js language="js" title="Request" tab="1"
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_example_123456789');

const claimAttempt = await workos.agents.linkClaimAttemptToExternalUser({
  claimAttemptToken: 'cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY',
  user: {
    email: 'alice@example.com',
    externalId: 'user_abc123',
  },
});
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.agents.update_attempts(
  type: "link_external_user",
  claim_attempt_token: "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
  user: { email: "alice@example.com", external_id: "user_abc123" }
)
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.agents.update_attempts(
    type="link_external_user",
    claim_attempt_token="cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
    user={"email": "alice@example.com", "external_id": "user_abc123"},
)
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.Agents().UpdateAttempts(context.Background(), &workos.AgentsUpdateAttemptsParams{
		Type:              "link_external_user",
		ClaimAttemptToken: "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
		User:              map[string]any{"email": "alice@example.com", "external_id": "user_abc123"},
	})
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->agents()
    ->updateAttempts(
        type: "link_external_user",
        claimAttemptToken: "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
        user: ["email" => "alice@example.com", "external_id" => "user_abc123"],
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.agents.AgentsApi.UpdateAttemptsOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

UpdateAttemptsOptions options =
    UpdateAttemptsOptions.builder()
        .type("link_external_user")
        .claimAttemptToken("cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY")
        .user(Map.of("email", "alice@example.com", "external_id", "user_abc123"))
        .build();

workos.agents.updateAttempts(options);
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.Agents.UpdateAttemptsAsync(new AgentsUpdateAttemptsOptions {
    Type = "link_external_user",
    ClaimAttemptToken = "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY",
    User =
        new Dictionary<string, object> {
            { "email", "alice@example.com" },
            { "external_id", "user_abc123" },
        },
});
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::agents::UpdateAttemptsParams;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .agents()
        .update_attempts(
            UpdateAttemptsParams {
                type_: "link_external_user".into(),
                claim_attempt_token: "cla_tkn_01EHWNCE74X7JSDV0X3SZ3KJNY".into(),
                user: serde_json::json!({
                    "email": "alice@example.com",
                    "external_id": "user_abc123",
                }),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "id": "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY",
  "status": "unverified",
  "user_code": "BCDF-GHJK",
  "organizations": [
    {
      "id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY",
      "name": "Acme Corp"
    }
  ]
}
```

:::

## Revoke an agent registration

Revoke an agent registration by ID. Revocation is permanent: the registration, its identity assertions, and every access token or API key issued from it stop working, and the agent must register again. Revoking an already revoked registration succeeds and returns the original `revoked_at`. The registration is scoped to the environment of the API key used to authenticate the request.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/agents/registrations/agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY/revoke" \
  --header "Authorization: Bearer sk_example_123456789"
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.agents.revoke_registration(id: "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.agents.revoke_registration(id_="agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.Agents().RevokeRegistration(context.Background(), "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->agents()
    ->revokeRegistration(id: "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;

WorkOS workos = new WorkOS("sk_example_123456789");

workos.agents.revokeRegistration("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.Agents.RevokeRegistrationAsync("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY");
```

```rust language="rust" title="Request" tab="1"
use workos::Client;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .agents()
        .revoke_registration("agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY")
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "id": "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY",
  "agent_identity": {
    "id": "agent_identity_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "userland_user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z"
  },
  "organization_id": "org_01EHQMYV6MBK39QC5PZXHY59C3",
  "status": "revoked",
  "revoked_at": "2026-01-15T12:00:00.000Z",
  "kind": "service_auth",
  "claim": {
    "id": "agent_reg_claim_01EHWNCE74X7JSDV0X3SZ3KJNY",
    "claim_completion": {
      "id": "agent_reg_claim_attempt_01EHWNCE74X7JSDV0X3SZ3KJNY",
      "created_at": "2026-01-15T12:00:00.000Z",
      "updated_at": "2026-01-15T12:00:00.000Z",
      "expires_at": "2026-01-15T12:00:00.000Z",
      "claimed_at": "2026-01-15T12:00:00.000Z"
    },
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z",
    "expires_at": "2026-01-15T12:00:00.000Z"
  },
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Validate an agent credential

Validate an agent credential — an API key or access token — against the environment of the API key used to authenticate the request. This is a read-only check: it never consumes or mutates the credential.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/agents/credentials/validate" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "type": "api_key",
        "credential": "sk_agent_example_1234567890"
    }
BODY
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.agents.create_validate(
  type: "api_key",
  credential: "sk_agent_example_1234567890"
)
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.agents.create_validate(type="api_key", credential="sk_agent_example_1234567890")
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.Agents().CreateValidate(context.Background(), &workos.AgentsCreateValidateParams{
		Type:       "api_key",
		Credential: "sk_agent_example_1234567890",
	})
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->agents()
    ->createValidate(
        type: "api_key",
        credential: "sk_agent_example_1234567890",
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.agents.AgentsApi.CreateValidateOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

CreateValidateOptions options = CreateValidateOptions.builder()
                                    .type("api_key")
                                    .credential("sk_agent_example_1234567890")
                                    .build();

workos.agents.createValidate(options);
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.Agents.CreateValidateAsync(new AgentsCreateValidateOptions {
    Type = "api_key",
    Credential = "sk_agent_example_1234567890",
});
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::agents::CreateValidateParams;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .agents()
        .create_validate(
            CreateValidateParams {
                type_: "api_key".into(),
                credential: "sk_agent_example_1234567890".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "valid": true,
  "registration_id": "agent_reg_01EHWNCE74X7JSDV0X3SZ3KJNY",
  "expires_at": "2026-01-15T12:00:00.000Z"
}
```

:::

### agent_registration

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Unique identifier of the agent registration. |
| `agent_identity` | object | Yes | The agent identity associated with this registration. |
| `organization_id` | string | Yes | Identifier of the organization the agent is registered to. |
| `status` | "unverified" \| "verified" \| "expired" \| "revoked" | Yes | The current verification status of the registration. |
| `revoked_at` | string | No | The timestamp when the registration was revoked, or `null` if it has not been revoked. |
| `kind` | "anonymous" \| "service_auth" \| "identity_assertion" | Yes | The kind of agent registration. |
| `claim` | object | No | The claim associated with this registration, or `null` if the registration has no claim. |
| `created_at` | string | Yes | The timestamp when the registration was created. |
| `updated_at` | string | Yes | The timestamp when the registration was last updated. |

### GET /agents/registrations/{id}

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The unique ID of the agent registration. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Unique identifier of the agent registration. |
| `agent_identity` | object | The agent identity associated with this registration. |
| `organization_id` | string | Identifier of the organization the agent is registered to. |
| `status` | "unverified" \| "verified" \| "expired" \| "revoked" | The current verification status of the registration. |
| `revoked_at` | string | The timestamp when the registration was revoked, or `null` if it has not been revoked. |
| `kind` | "anonymous" \| "service_auth" \| "identity_assertion" | The kind of agent registration. |
| `claim` | object | The claim associated with this registration, or `null` if the registration has no claim. |
| `created_at` | string | The timestamp when the registration was created. |
| `updated_at` | string | The timestamp when the registration was last updated. |

### PATCH /agents/claims/attempts

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | "link_external_user" | Yes | The operation to perform on the claim attempt. Currently only `link_external_user` is supported. |
| `claim_attempt_token` | string | Yes | The token identifying the claim attempt. |
| `user` | object | Yes | The user to attach to the claim attempt, identified by email and external ID. |
| `organization_id` | string | No | The organization to place the agent in. Required when the user belongs to more than one organization. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | The agent registration ID. |
| `status` | "unverified" \| "verified" \| "expired" \| "revoked" | Current status of the agent registration. |
| `user_code` | string | The user code the agent needs to complete the claim. |
| `organizations` | object[] | Organizations the user belongs to, offered as placement choices. |

### POST /agents/registrations/{id}/revoke

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The unique ID of the agent registration. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Unique identifier of the agent registration. |
| `agent_identity` | object | The agent identity associated with this registration. |
| `organization_id` | string | Identifier of the organization the agent is registered to. |
| `status` | "unverified" \| "verified" \| "expired" \| "revoked" | The current verification status of the registration. |
| `revoked_at` | string | The timestamp when the registration was revoked, or `null` if it has not been revoked. |
| `kind` | "anonymous" \| "service_auth" \| "identity_assertion" | The kind of agent registration. |
| `claim` | object | The claim associated with this registration, or `null` if the registration has no claim. |
| `created_at` | string | The timestamp when the registration was created. |
| `updated_at` | string | The timestamp when the registration was last updated. |

### POST /agents/credentials/validate

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | "api_key" \| "access_token" | Yes | The kind of credential being validated — an agent API key or an agent access token. |
| `credential` | string | Yes | The credential value to validate: the API key value for `api_key`, or the access token (JWT) for `access_token`. |
| `audience` | string | No | When provided, the access token's `aud` claim is verified against this value. Tokens issued for a different resource are rejected. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `valid` | boolean | Whether the presented credential is valid. |
| `registration_id` | string | Identifier of the agent registration the credential belongs to, or `null` when the credential is invalid. |
| `expires_at` | string | The timestamp when the credential expires, or `null` when the credential is invalid. |