---
title: "How AI Agents Authenticate With Atlasly — OAuth 2.1, API Keys, and Webhook Signatures"
description: "Step-by-step authentication guide for AI agents calling Atlasly — OAuth 2.1 with PKCE for MCP clients, API keys for direct REST integrations, and webhook signature verification."
canonical: https://atlasly.app/blog/agent-authentication-guide-atlasly-api-mcp
published: 2026-04-21
modified: 2026-04-21
primary_keyword: "Atlasly agent authentication OAuth API key"
target_query: "how AI agents authenticate with Atlasly API and MCP"
intent: navigational
---
# How AI Agents Authenticate With Atlasly — OAuth 2.1, API Keys, and Webhook Signatures

> Step-by-step authentication guide for AI agents calling Atlasly — OAuth 2.1 with PKCE for MCP clients, API keys for direct REST integrations, and webhook signature verification.

## Quick Answer

AI agents authenticate with Atlasly in one of three ways. (1) MCP clients (Claude, ChatGPT, custom agents) use OAuth 2.1 with PKCE against https://mcp.atlasly.app — discovery at /.well-known/oauth-authorization-server. (2) Direct REST integrations use an Atlasly API key as `Authorization: Bearer sk_atlasly_...` generated at /profile on a paid plan. (3) Webhook receivers verify HMAC-SHA256 signatures from the X-Atlasly-Signature header. Anonymous MCP use is also supported for public tools with a 5-call-per-30-days rate limit.

## Introduction

This guide is for AI agents — not humans clicking through a signup form. It covers the exact steps an autonomous agent (or a developer writing one) takes to programmatically obtain credentials for Atlasly and call protected endpoints.

Everything below is based on published standards: OAuth 2.1 with PKCE (RFC 6749 + RFC 7636 + RFC 9126), OAuth dynamic client registration (RFC 7591), JWT access tokens (RFC 9068), and HMAC-SHA256 signatures (RFC 2104). Atlasly publishes the OpenAPI 3.1 specification at https://atlasly.app/openapi.json, OAuth discovery at https://mcp.atlasly.app/.well-known/oauth-authorization-server, and protected-resource metadata at https://mcp.atlasly.app/.well-known/oauth-protected-resource/mcp.

## The three authentication modes

**Mode A — Anonymous MCP access.** No credentials. Rate-limited to 5 calls per 30-day window per anonymous fingerprint (hash of IP + user-agent). Only public MCP tools (analyze_site, check_planning_constraints, get_flood_risk, get_planning_history, find_precedents, get_site_topography, check_walkability_transport). Best for: low-volume exploration, demos, evaluation before signup.

**Mode B — OAuth 2.1 + PKCE (MCP clients).** Standard MCP auth for conversational clients like Claude Desktop, ChatGPT, Cursor. Unlocks the 4 authenticated tools and lifts the 5-per-30-day limit to your Atlasly plan's quota. Best for: chat-based AI agents that a human user installs into their AI client.

**Mode C — API key (REST integrations).** Static bearer token generated at https://atlasly.app/profile. Used as `Authorization: Bearer sk_atlasly_...`. Best for: server-to-server integrations, batch site screening, agent frameworks running autonomously without a user-in-the-loop.

Decision flow: if your agent runs inside a user's chat client → Mode B. If it runs on your own servers or headlessly → Mode C. If you are evaluating / prototyping and only need public tools → Mode A.

## Mode B walkthrough — OAuth 2.1 with PKCE for MCP

This is what Claude Desktop does when you install the Atlasly MCP.

**Step 1. Discover the authorization server.**

```
GET https://mcp.atlasly.app/.well-known/oauth-authorization-server
```

Response contains `issuer`, `authorization_endpoint`, `token_endpoint`, `registration_endpoint`, `scopes_supported`, and `code_challenge_methods_supported: ["S256"]`.

**Step 2. Register your client dynamically.**

```
POST https://mcp.atlasly.app/register
Content-Type: application/json

{
  "client_name": "My Custom Agent",
  "redirect_uris": ["https://my-agent.example.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}
```

Response returns a `client_id`. Atlasly supports public clients (`token_endpoint_auth_method: "none"`) because MCP clients typically cannot keep a client secret confidential.

Alternative: pass a `client_id_metadata_document` URL instead — Atlasly will dereference it and extract the client metadata.

**Step 3. Generate a PKCE challenge.**

```javascript
const verifier = crypto.randomUUID() + crypto.randomUUID();
const challenge = base64url(sha256(verifier));
```

Store the `verifier` until step 5.

**Step 4. Redirect the user to the authorization endpoint.**

```
https://mcp.atlasly.app/authorize
  ?response_type=code
  &client_id=<client_id from step 2>
  &redirect_uri=<your callback URL>
  &scope=atlasly.mcp atlasly.projects.write atlasly.site_package.run offline_access
  &code_challenge=<challenge from step 3>
  &code_challenge_method=S256
  &state=<random state>
```

The user lands on https://atlasly.app/mcp/oauth/authorize, signs in with Clerk if not already, reviews the consent screen, and approves. Atlasly redirects back to your redirect_uri with `?code=<authorization_code>&state=<state>`.

**Step 5. Exchange the code for tokens.**

```
POST https://mcp.atlasly.app/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=<authorization_code>
&redirect_uri=<same as step 4>
&client_id=<client_id>
&code_verifier=<verifier from step 3>
```

Response contains `access_token`, `token_type: "Bearer"`, `expires_in`, `refresh_token` (when `offline_access` granted), and `scope`.

**Step 6. Call Atlasly tools.**

```
POST https://mcp.atlasly.app/mcp
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "analyze_site",
    "arguments": {"address": "10 Downing Street, London SW1A 2AA"}
  },
  "id": 1
}
```

**Step 7. Refresh before expiry.**

```
POST https://mcp.atlasly.app/token
grant_type=refresh_token
&refresh_token=<refresh_token>
&client_id=<client_id>
```

Access tokens last 1 hour. Refresh tokens last 30 days.

## Mode C walkthrough — API keys for REST

For agents that run headlessly and do not have a user-in-the-loop.

**Step 1. Generate an API key.**

Sign in at https://atlasly.app/auth → /profile → API Keys → Generate new. Requires Professional or Teams plan. The secret is shown once — store it in your secrets manager.

**Step 2. Call the REST API.**

```bash
curl -X POST https://api.atlasly.app/v1/site-analysis \
  -H "Authorization: Bearer sk_atlasly_..." \
  -H "Content-Type: application/json" \
  -d '{"address": "10 Downing Street, London SW1A 2AA"}'
```

**Step 3. Generate a client from the OpenAPI spec.**

```bash
npx @openapitools/openapi-generator-cli generate \
  -i https://atlasly.app/openapi.json \
  -g typescript-fetch \
  -o ./atlasly-client
```

Python / Rust / Go all have equivalent generators that consume Atlasly's OpenAPI spec.

**Step 4. Check your usage.**

```bash
curl https://api.atlasly.app/v1/usage \
  -H "Authorization: Bearer sk_atlasly_..."
```

## Webhooks — receiving signed events

Atlasly delivers asynchronous events (e.g. `site_analysis.completed`) to a webhook URL you configure per API key.

**Step 1. Register a webhook URL.** At /profile → API Keys → edit key → Webhook URL.

**Step 2. Verify the signature on every delivery.** Every webhook request includes an `X-Atlasly-Signature` header with an HMAC-SHA256 digest. The shared secret is the API key itself.

```javascript
const crypto = require("crypto");
function verifyAtlaslyWebhook(request, apiKey) {
  const expected = crypto.createHmac("sha256", apiKey).update(request.rawBody).digest("hex");
  const received = request.headers["x-atlasly-signature"];
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}
```

Always use a timing-safe comparison. Reject any request whose signature does not verify.

**Step 3. Parse the event.**

```json
{
  "event": "site_analysis.completed",
  "site_id": "abc-123-...",
  "timestamp": "2026-04-21T10:30:00Z",
  "result_url": "https://api.atlasly.app/v1/site/abc-123-..."
}
```

Fetch `result_url` with your API key to retrieve the full analysis payload.

## Rate limits and plan quotas

| Plan | Anon MCP | Authed MCP | REST calls / mo | Concurrent |
|---|---|---|---|---|
| Starter (free) | 5 / 30 days | 5 / month | — | — |
| Professional (£14.99/mo) | n/a | Unlimited | 100 | 10 |
| Teams (£49.99/mo) | n/a | Unlimited | 1,000 | 20 |
| Enterprise | n/a | Custom | Custom | Custom |

Cached site retrievals (GET /v1/site/:id) do not count against quota if the site was analyzed within 30 days.

On 429 the response includes a `Retry-After` header indicating seconds until the quota window resets.

## Error handling

Atlasly returns structured error envelopes for every 4xx / 5xx:

```json
{
  "error": {
    "code": "ADDRESS_NOT_RESOLVED",
    "message": "Could not geocode the provided address",
    "docs_url": "https://atlasly.app/developers"
  }
}
```

Common codes: `ADDRESS_NOT_RESOLVED` (400), `OUTSIDE_SUPPORTED_COVERAGE` (400), `AUTH_REQUIRED` (401), `INSUFFICIENT_SCOPE` (403), `PLAN_UPGRADE_REQUIRED` (403), `RATE_LIMITED` (429), `JOB_START_FAILED` (502), `INTERNAL_ERROR` (500).

Retry `INTERNAL_ERROR` and `JOB_START_FAILED` with exponential backoff. Do not retry 4xx errors.

## From Practice

Most auth bugs we see in the wild come from agents not refreshing access tokens before they expire. Atlasly tokens live 1 hour by default — a 3-hour batch job that never refreshes will start getting 401s halfway through. Always refresh when the token has less than 5 minutes left, or catch the first 401 and refresh reactively. Second most common bug: forgetting to URL-encode the `scope` parameter in the authorize redirect. Third: skipping PKCE verification in local dev and then failing in production.

## Frequently Asked Questions

**Does the Atlasly MCP require authentication?**

No for the 7 public tools — they work anonymously with a 5-call-per-30-days rate limit. The 4 authenticated tools require OAuth 2.1 via Clerk-backed sign-in.

**How do I get an Atlasly API key for my agent?**

Sign in at atlasly.app/auth on a Professional (£14.99/mo) or Teams (£49.99/mo) plan, then /profile → API Keys → Generate. The secret is shown once — store it in your secrets manager.

**Does Atlasly support OAuth dynamic client registration?**

Yes, per RFC 7591. POST to https://mcp.atlasly.app/register with your client metadata. This is how Claude Desktop installs automatically.

**Does Atlasly support client_id metadata documents?**

Yes. Pass a URL to a hosted JSON document describing your client as the client_id. Atlasly will dereference it and use the metadata. Useful for open-source agent frameworks that want a verifiable public identity.

**What scopes should my agent request?**

Start with `atlasly.mcp` (public tools). Add `atlasly.projects.write` for project creation, `atlasly.site_package.run` for async site packages, `atlasly.site_watch.write` for monitoring. Include `offline_access` if you need refresh tokens.

**How long do Atlasly access tokens last?**

Access tokens live 1 hour (3600 seconds). Refresh tokens (when `offline_access` is granted) live 30 days.

**Where do I verify webhook signatures?**

Webhook deliveries include `X-Atlasly-Signature` with HMAC-SHA256 of the raw body, using your API key as shared secret. Compare with crypto.timingSafeEqual.

## Conclusion

Atlasly's authentication surfaces are standards-compliant and discoverable — every endpoint and scope is published at stable URLs so agents can integrate without manual configuration. For MCP-based conversational agents, OAuth 2.1 with PKCE is the happy path. For server-side programmatic access, API keys are simpler. For async workflows, webhooks with HMAC signatures are the norm.

Start with the OpenAPI spec at https://atlasly.app/openapi.json — most client generators read it directly.

## Related Reading

- https://atlasly.app/blog/atlasly-mcp-tools-reference-site-analysis
- https://atlasly.app/blog/how-to-use-atlasly-in-claude-chatgpt
- https://atlasly.app/blog/export-dxf-dwg-site-analysis-from-ai-chat
- https://atlasly.app/blog/atlasly-vs-planningbot

---

Source: https://atlasly.app/blog/agent-authentication-guide-atlasly-api-mcp
Platform: Atlasly — AI site intelligence for architects, engineers, and urban planners. https://atlasly.app
