---
title: "Agentic Registration: How an AI Agent Signs Up for Bright Data With auth.md"
slug: agentic-registration
date: 2026-09-09T14:41:21+00:00
modified: 2026-09-22T11:54:49+00:00
permalink: https://brightdata.com/blog/ai/agentic-registration
type: blog
---

[ Blog ](https://brightdata.com/blog "Blog") / [AI](https://brightdata.com/blog/ai)







 [AI](https://brightdata.com/blog/ai)

# Agentic Registration: How an AI Agent Signs Up for Bright Data With auth.md

How an AI agent registers for Bright Data via auth.md and gets a working API token, with a human only confirming an email code.

 15 min read





 [ ](https://brightdata.com/blog/authors/daniel-shashko)

 [Daniel Shashko

Web Data &amp; AI Expert

 ](https://brightdata.com/blog/authors/daniel-shashko)





 ![Agentic Registration](https://media.brightdata.com/2026/09/Agentic-Registration.png)





**TL;DR**

An AI agent can create a Bright Data account and receive a working API token without a human filling in a signup form. The protocol lives at `https://brightdata.com/auth.md` and is advertised in discovery metadata under an `agent_auth` block.

Three calls:

1. `POST /users/auth/agent_registration/auth` with the user’s email. Returns a `claim_token`. No credential yet.
2. The user reads a 6-character code from their inbox and gives it to the agent.
3. `POST /users/auth/agent_registration/claim/complete` with the `claim_token` and the code. Returns the API token.

The account starts with 5,000 free credits per month, a $2 trial credit valid 7 days, and three pre-created zones: `agent_serp`, `agent_unlocker`, `agent_browser_api`. The first call to any of them works with zero setup.

## The problem

Every signup form assumes a human. Pick a plan, click a verification link, open a dashboard, find settings, copy a key, paste it somewhere.

That breaks when the thing needing the key is an agent. A coding agent asked to pull pricing from 40 retailers can write the scraper, handle retries, and parse the output. It cannot click a button in a browser it does not have.

So it stops at step zero. And the stop is harder than it looks, because the obstacle is not capability.

## The agent is not allowed to, even when it can

The obvious objection is that browser automation solves this. Give the agent a Chrome extension or a Playwright session and it can fill in a signup form like anyone else.

It can. It is not permitted to.

Anthropic’s browser agents are prohibited from creating accounts on a user’s behalf. This is not a soft preference and not a permission prompt. Account creation sits on the prohibited list alongside handling banking data and making permanent deletions, which means it is refused even when the user explicitly asks and grants permission. The instruction is to direct the user to create the account themselves.

Two further rules make a signup form close to unusable even without that one. Claude respects bot detection and human verification systems and does not complete them on a user’s behalf. And accepting terms, conditions, or agreements requires explicit user approval each time, per Anthropic’s [published safety documentation](https://www.anthropic.com/news/claude-for-chrome). A standard signup form asks an agent to do all three at once: create an account, clear a CAPTCHA, and accept a ToS.

This is a reasonable line to draw. An agent that can silently register accounts against arbitrary email addresses is an abuse engine. The restriction exists for good reasons and it is not going to be relaxed.

The consequence for a data provider is specific. A signup form is not a slow path for an agent. It is a closed one. Handing the agent a browser does not help, because the browser was never the blocker.

**auth.md puts the consent where the policy needs it.** The flow never asks the agent to impersonate a human. The agent makes HTTP calls. The human retrieves a one-time code from their own inbox and hands it over. The account cannot be created without the user’s active participation, so the user cannot be unaware it happened. The agent is a client, not a stand-in.

That is why the OTP step is in the protocol rather than engineered away. It is not leftover friction from a human signup flow. It is the consent mechanism, and it is what makes this something an agent is permitted to complete rather than merely capable of completing.

## How an agent finds it

An agent that has never seen Bright Data can reach the flow from standard metadata.

```none
GET https://brightdata.com/.well-known/oauth-authorization-server
```

The response carries an `agent_auth` block:

```none
{
  "agent_auth": {
    "skill": "https://brightdata.com/auth.md",
    "register_uri": "https://brightdata.com/users/auth/agent_registration/auth",
    "claim_uri": "https://brightdata.com/users/auth/agent_registration/claim",
    "identity_types_supported": ["identity_assertion"],
    "identity_assertion": {
      "assertion_types_supported": ["verified_email"],
      "credential_types_supported": ["api_key"]
    }
  }
}
```

That block is the contract. `github_token` and `anonymous` will appear there if and when they ship. Use only the methods the metadata lists, not methods remembered from an older copy of the document.

There is also protected resource metadata for the API:

```none
GET https://api.brightdata.com/.well-known/oauth-protected-resource
```

```none
{
  "resource": "https://api.brightdata.com/",
  "resource_name": "Bright Data API",
  "authorization_servers": ["https://brightdata.com"],
  "scopes_supported": ["serp", "unlocker", "wsapi", "scraper_studio",
      "discover", "browser", "usage:read"],
  "bearer_methods_supported": ["header"]
}
```

**The endpoints self-document at runtime.** `GET https://brightdata.com/users/auth/agent_registration` returns a machine-readable markdown copy of the endpoint contracts and the error table. If that response and `auth.md` ever disagree, the endpoint response is the live truth. It can be switched off independently, in which case it returns `instructions_disabled` with a 404 and the agent falls back to `auth.md`.

## Four ways in

Programmatic registration is the fully automated path. It is not the only one.

PathWhat the human doesUse whenEmail registrationReads one code from their inboxThe agent needs its own credential and no browser session existsAPI tokenPastes a token onceThe user already has an account. Token from `https://brightdata.com/cp/setting/users`Hosted MCP with OAuthCompletes OAuth in a browserA browser is available. Connect to `https://mcp.brightdata.com/mcp`CLI loginClicks through browser or device flowTerminal context. `npx @brightdata/cli login`, or `brightdata login --github` if the GitHub CLI is authenticatedThe rest of this guide covers the first one.

## Step 1: Discover

Read the authorization server metadata and confirm which assertion types are live. Today that is `verified_email` only.

```none
curl https://brightdata.com/.well-known/oauth-authorization-server
```

## Step 2: Register

Use the user’s real mailbox address. Disposable domains and plus-aliased addresses such as `<a class="__cf_email__" data-cfemail="6e1b1d0b1c451a0f092e0b160f031e020b400d0103" href="/cdn-cgi/l/email-protection">[email protected]</a>` are rejected.

```none
curl -X POST https://brightdata.com/users/auth/agent_registration/auth \
  -H "Content-Type: application/json" \
  -d '{
    "type": "identity_assertion",
    "assertion_type": "verified_email",
    "assertion": "<a class="__cf_email__" data-cfemail="196c6a7c6b597c61787469757c377a7674" href="/cdn-cgi/l/email-protection">[email protected]</a>",
    "client": "claude-code"
  }'
```

`client` is optional but recommended. Declaring the agent name, up to 100 characters, gives support and diagnostics something to work with.

The response carries no credential:

```none
{
  "claim_token": "<uuid-v4>",
  "state": "pending",
  "otp_expires_at": "<ISO 8601 timestamp>",
  "claim_token_expires_at": "<ISO 8601, 24 hours from registration by default>"
}
```

`claim_token` is a UUID v4 and is the registration’s own identifier. There is no separate `registration_id`. Keep it in memory and pass it to step 3 as is.

Before sending any user identity, show the user the service name, Bright Data, and what the account will be able to do. Calling these endpoints asserts acceptance of the Bright Data Terms of Service and Acceptable Use Policy on behalf of the email address supplied.

## Step 3: Verify

Bright Data emails the user a 6-character alphanumeric, mixed-case code, valid 10 minutes by default. Ask the user to read it back.

```none
curl -X POST https://brightdata.com/users/auth/agent_registration/claim/complete \
  -H "Content-Type: application/json" \
  -d '{
    "claim_token": "<uuid-v4>",
    "otp": "aB3xY9"
  }'
```

The credential is issued here:

```none
{
  "claim_token": "<uuid-v4>",
  "credential": { "token": "<api_token>", "id": "<token_id>" },
  "zones": {
    "serp":        { "zone_id": "agent_serp",        "status": "success" },
    "unlocker":    { "zone_id": "agent_unlocker",    "status": "success" },
    "browser_api": { "zone_id": "agent_browser_api", "status": "success" }
  }
}
```

To resend the code, post the `claim_token` to `/users/auth/agent_registration/claim`. That invalidates the previous code, does not reset the remaining attempt count, and is limited to 3 resends per registration with a 60-second minimum interval.

The account is now live on the free tier plus the $2 trial credit. Pending registrations that are never verified expire after 24 hours.

## Step 4: Use the credential

Web search through the SERP zone:

```none
curl -X POST https://api.brightdata.com/request \
  -H "Authorization: Bearer <api_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "zone": "agent_serp",
    "url": "https://www.google.com/search?q=web+scraping+tools",
    "format": "json"
  }'
```

Scrape a protected page through Web Unlocker:

```none
curl -X POST https://api.brightdata.com/request \
  -H "Authorization: Bearer <api_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "zone": "agent_unlocker",
    "url": "https://example.com",
    "format": "raw"
  }'
```

For the Browser API, connect Playwright, Puppeteer, or Selenium over CDP to the `agent_browser_api` zone. This draws on the $2 trial credit. Setup is at `https://docs.brightdata.com/scraping-automation/scraping-browser/quickstart`.

For the full MCP tool set, use `https://mcp.brightdata.com/mcp?token=<api_token>`.

Web Scraper APIs are not zone-based and are not auto-provisioned by registration. They run through a separate trigger, poll, and download mechanism documented at `https://docs.brightdata.com/datasets/introduction`.

## What the account gets

ItemDetailFree credits5,000 per month, renewed monthly. Covers Web Unlocker, SERP, Web Scraper APIs, Scraper StudioTrial credit$2 one-time, valid 7 days, any product including Browser API. Adding a payment method grants a further $5 and extends the trial to 30 daysZones`agent_serp`, `agent_unlocker`, `agent_browser_api`, pre-createdUsage and billingRead-only. Check the balance, no access to payment methods or invoicesToken lifetimeOn the order of a year by default. Exact expiry is not returnedNot included: proxy networks, account administration, and creating or editing zones. Residential proxies always require a KYC-verified business account through the Control Panel. The human can add funds and lift restrictions there at any time.

The token’s permission profile is deliberately minimal. It is read-only for admin and billing and cannot create or edit zones, which is why the three it needs are pre-provisioned.

## Seven behaviors that break naive implementations

These are the parts an agent gets wrong if it treats the flow as a generic signup form.

**A 200 on step 2 is not proof the email is new.** If the address already belongs to a Bright Data account, or is filtered by a domain or email allow-list during a controlled rollout, the response shape is identical to success and no code is sent. The existing account’s owner receives a separate notice email instead. This is intentional and not distinguishable from success. If a user reports never receiving a code, ask them to check spam and confirm they do not already have an account, rather than retrying in a loop.

**Repeating step 2 does not restart anything.** Calling `/auth` again for the same email while a registration is pending returns the same `claim_token` and unchanged expiry timestamps. Use the resend endpoint for a fresh code.

**Zone provisioning is per-product and fails independently.** Check every entry under `zones`. One product reporting `"status": "failed"` while the others succeed means retry that product later, not that the whole registration failed.

**`/claim/complete` is idempotent.** Retrying with the same `claim_token` and code after a timeout or network error returns the identical result. It does not create a second account, issue a second credential, or grant entitlements twice. Retry safely.

**The credential is a secret.** Never print, log, or echo `credential.token` into chat output, transcripts, command-line arguments, or any file an unintended party could read. Store it in a secret manager, an OS credential store, or a `.env` file excluded from version control with restrictive permissions. Not in plaintext source, shell history, or logs.

**Rate limits apply across five dimensions.** Defaults: 3 registration starts per hour per email, 60 per hour per source IP, 30 per hour per network range, 50 per hour per email domain, 1,000 per hour globally. Exceeding any one returns `rate_limited`. Registrations also pass fraud screening.

**A 401 on a working credential means restart discovery.** Drop the credential and go back to step 1. Do not retry the call.

## Error codes

Every non-2xx response from `/auth`, `/claim`, and `/claim/complete` uses the same shape: `{"error": "", "error_description": "<actionable next step>"}`. The description is a next step, not prose. No internal fraud thresholds, scores, or vendor names are ever included.

CodeHTTPWhereWhat to do`invalid_request`400all threeFix the JSON body`email_not_accepted`400`/auth`Disposable, aliased, or invalid address. Ask for the real mailbox`registration_denied`403`/auth`, `/claim/complete`Refused. Do not retry. Use a fallback path with a human present`browser_signup_required`403`/auth`This email must sign up in a browser. Do not retry. Tell the human to sign up at the Control Panel with the same address`fraud_check_unavailable`503`/auth`Retryable. Wait at least the `Retry-After` seconds, retry the identical request, double the wait on each failure, 3 attempts total, then fall back to a human path`rate_limited`429anyBack off and retry later`invalid_claim_token`400`/claim`, `/claim/complete`Invalid, unknown, or exhausted (5 OTP attempts or 3 resends). Restart registration`otp_invalid`400`/claim/complete`Ask the user to re-read the code. After 5 wrong attempts the claim is permanently invalidated`otp_expired`400`/claim/complete`Resend via `/claim`. Codes last 10 minutes by default`claim_expired`400`/claim/complete`Pending registration passed 24 hours. Restart`registration_disabled`503`/auth`New registrations temporarily off. Use a fallback path`instructions_disabled`404GET discovery endpointSelf-documenting endpoint is off. Rely on auth.md`invalid_github_token`401`/auth`Reserved. Not returned today`email_unverified`401`/auth`Reserved. Not returned todayRetry 5xx with exponential backoff. Do not retry the same 4xx payload unless the table says to.

## Revocation

Agents do not initiate revocation. There is no endpoint for an agent to hand a credential back.

If a credential stops working and the API returns 401, discard it and restart discovery from step 1. That is the entire contract. An agent holding a dead token should not retry it, should not attempt to refresh it, and should not assume the account is gone. It should go back to the metadata and start again.

## Claiming the account later

A human can complete standard signup later, with a password, GitHub, or Google, using the same email address, and get full access to that same account. It does not create a duplicate and it does not invalidate the credential the agent is already using. Password reset on that address is the way into the Control Panel from a cold start.

## Not shipped yet

Stated explicitly so agents do not attempt it and waste a request.

**GitHub token assertion** is planned and not scheduled. The design reads the token from an authenticated GitHub CLI, validates it against GitHub server-side, reads the verified primary email, and keys the account on the GitHub numeric ID. The token is used once and never stored. Because the identity is already verified, the credential returns immediately with no code step. Minimal scopes would be `read:user` and `user:email`, and a GitHub account without a verified primary email would be rejected.

None of that is implemented. The server accepts `verified_email` only and rejects anything else as `invalid_request`. The `invalid_github_token` and `email_unverified` codes are reserved and not returned today.

**Anonymous registration** is planned and not scheduled.

The rule is the same for both: read `assertion_types_supported` from the metadata and use only what is listed. When these ship, the metadata is where they appear first.

## Reference

Every URL in the protocol:

URLPurpose`https://brightdata.com/auth.md`The protocol document. Canonical`https://brightdata.com/.well-known/oauth-authorization-server`Authorization server metadata with the `agent_auth` block`https://api.brightdata.com/.well-known/oauth-protected-resource`Protected resource metadata, scopes and bearer methods`https://brightdata.com/users/auth/agent_registration`Live self-documenting mirror of contracts and errors`.../agent_registration/auth`Start registration`.../agent_registration/claim`Resend the code`.../agent_registration/claim/complete`Submit the code, receive the token`https://api.brightdata.com/request`SERP and Web Unlocker calls`https://mcp.brightdata.com/mcp`Hosted MCP, full tool set`https://brightdata.com/cp/setting/users`Where a human finds an existing API token`https://docs.brightdata.com`API reference`https://docs.brightdata.com/llms.txt`Documentation index`https://docs.brightdata.com/scraping-automation/scraping-browser/quickstart`Browser API setup`https://docs.brightdata.com/datasets/introduction`Web Scraper APIs, trigger, poll, downloadCLI: `npm install -g @brightdata/cli`

SDKs: `npm install @brightdata/sdk` or `pip install brightdata-sdk`

## FAQ

**Can an AI agent create a Bright Data account without a human?**

Almost entirely. The agent makes every HTTP call. The human’s only action is reading a 6-character code from their email and giving it to the agent. No form, no dashboard, no browser.

**Why can’t the agent just fill in the normal signup form with a browser tool?**

Because it is not allowed to. Anthropic prohibits its browser agents from creating accounts on a user’s behalf, even with explicit user permission, and separately instructs them not to complete CAPTCHAs or human verification. A signup form asks for both. The auth.md flow avoids this by never asking the agent to act as a human.

**Where is the protocol documented?**

`https://brightdata.com/auth.md`, mirrored in machine-readable form at `https://brightdata.com/users/auth/agent_registration`.

**How does an agent discover the endpoints?**

From the `agent_auth` block in `https://brightdata.com/.well-known/oauth-authorization-server`.

**What does the agent get?**

A standard Bright Data API token, 5,000 free credits per month, a $2 trial credit valid 7 days, and three pre-provisioned zones for SERP, Web Unlocker, and Browser API.

**Does the token expire?**

On the order of a year by default. The exact expiry is not returned in the registration response.

**Can the agent create its own zones?**

No. The token is read-only for admin and billing. The three zones it needs are pre-provisioned.

**Can the agent revoke its own credential?**

No. Agents do not initiate revocation. If a credential returns 401, discard it and restart discovery.

**Can the agent use residential proxies?**

No. Those always require a KYC-verified business account through the Control Panel.

**Is this ID-JAG?**

No. It is a proprietary Bright Data agent registration flow.

## Try it

Point an agent at `https://brightdata.com/auth.md` and ask it to register. Three calls later it has a token, three working zones, and 5,000 free credits a month.



Contact usStart free trial

No credit card required











 [ ](https://www.linkedin.com/in/daniel-shashko/)

Daniel Shashko

 Web Data &amp; AI Expert



  6 years experience



Daniel Shashko is a Senior SEO/GEO at Bright Data, specializing in B2B marketing, international SEO, and building AI-powered agents, apps, and web tools.





 [ View all articles ](https://brightdata.com/blog/authors/daniel-shashko)











 Table of Contents







Data for AI

Supercharge your AI with instant and reliable access to web data. No blockers. No hassle.

Talk to an expert

Bright Data MCP

Get started with Bright Data’s Web MCP Server today with 5000 free monthly requests and unlock your AI’s full potential.

Start free now







 [ ](https://news.ycombinator.com/submitlink?t=Agentic+Registration%3A+How+an+AI+Agent+Signs+Up+for+Bright+Data+With+auth.md&u=https://brightdata.com/blog/ai/agentic-registration) [ ](https://www.linkedin.com/shareArticle?mini=true&title=Agentic+Registration%3A+How+an+AI+Agent+Signs+Up+for+Bright+Data+With+auth.md&url=https://brightdata.com/blog/ai/agentic-registration) [ ](http://www.reddit.com/submit?title=Agentic+Registration%3A+How+an+AI+Agent+Signs+Up+for+Bright+Data+With+auth.md&url=https://brightdata.com/blog/ai/agentic-registration)







##  You might also be interested in

 [ ](https://brightdata.com/blog/ai/web-scraping-with-glm "Web Scraping with GLM: Text and Visual Data Extraction")

 [AI





Antonello Zanini

Technical Writer





### Web Scraping with GLM: Text and Visual Data Extraction

Use GLM-5.3 with Bright Data’s Web Unlocker for AI-driven web scraping. Automatically extract text and visual data, bypassing common barriers.



 16-Sep-2026

 5 min read

 ](https://brightdata.com/blog/ai/web-scraping-with-glm)

 [ ](https://brightdata.com/blog/web-data/containers-as-a-service "Containers as a Service (CaaS): How to Use It for Web Data Pipelines and AI Agents")

 [Web Data





Antonello Zanini

Technical Writer





### Containers as a Service (CaaS): How to Use It for Web Data Pipelines and AI Agents

How Containers as a Service works, and how to scale a Bright Data web scraping pipeline across containers for AI agents.



 16-Sep-2026

 12 min read

 ](https://brightdata.com/blog/web-data/containers-as-a-service)

 [ ](https://brightdata.com/blog/ai/openhuman-with-bright-data "Production-Ready Web Access in OpenHuman Through the Bright Data CLI")

 [AI





Antonello Zanini

Technical Writer





### Production-Ready Web Access in OpenHuman Through the Bright Data CLI

Integrate Bright Data CLI with OpenHuman to enable production-ready web access and data collection for AI agents.



 09-Sep-2026

 12 min read

 ](https://brightdata.com/blog/ai/openhuman-with-bright-data)
