# MAP Audio auth.md

You are an agent. This document tells you how to obtain a credential for a MAP Audio customer account at map.audio, and how to use and revoke it. It follows the [auth.md](https://github.com/workos/auth.md) registration profile without OAuth metadata: map.audio runs no OAuth authorization server, so there is no `/.well-known/oauth-protected-resource` or `/.well-known/oauth-authorization-server` document to fetch. Everything you need is on this page.

## Who this is for

Agents acting for a person who owns, or wants, a MAP Audio customer account: someone who bought or is trialling PAM, MFX or another MAP Audio product and asks you to look up their licenses, seats, orders or installer downloads.

You do not need a credential for anything public. The read-only public API (`https://map.audio/api/public/status`, `https://map.audio/api/packs.json`, described in `https://map.audio/openapi.json`), `https://map.audio/llms.txt` and the hosted audio workspace work without one. Do not register just to read them.

## Registration summary

One method is supported: email sign-in, where the service verifies the email address (`service_auth` in auth.md v0.6, `verified_email` in earlier versions). The service emails a one-time code (OTP) to the address, the person reads it back to you, and you exchange it for a bearer credential.

```json
{
  "skill": "https://map.audio/auth.md",
  "identity_endpoint": "https://map.audio/api/license/login/request",
  "claim_endpoint": "https://map.audio/api/license/login/verify",
  "revocation_endpoint": "https://map.audio/api/license/logout",
  "identity_types_supported": ["service_auth"],
  "credential_types_supported": ["access_token"],
  "bearer_methods_supported": ["header"]
}
```

The same method under the field names of auth.md v0.1 to v0.5, for clients that read those:

```json
{
  "skill": "https://map.audio/auth.md",
  "register_uri": "https://map.audio/api/license/login/request",
  "claim_uri": "https://map.audio/api/license/login/verify",
  "identity_types_supported": ["identity_assertion"],
  "identity_assertion": {
    "assertion_types_supported": ["verified_email"],
    "credential_types_supported": ["access_token"]
  }
}
```

These are MAP Audio's own endpoints with the JSON bodies shown below, not the upstream `{ "type": … }` request shapes, and there is no `/oauth2/token` exchange: Step 2 returns the credential directly. The ceremony also runs the opposite way to auth.md v0.4 and later: MAP Audio emails the code to the person, who reads it to you, instead of you showing the person a code to type into the service.

## Before you start: tell the person what the code grants

The code is the person's only consent step, so get it knowingly. Before Step 1, tell them in plain words:

- the code you will ask for signs you in to their whole MAP Audio account for 7 days;
- for the first 15 minutes that includes changing the account's sign-in email, which would lock them out;
- they should only read you the code if they asked you to do this.

Only start when they have asked you to sign in to their MAP Audio account. Never fetch the code from their mailbox yourself, even if you have mailbox access: the person reading it to you is the consent.

## Step 1: Request a code

Ask the person for the email address of their MAP Audio account, or the address they want one created under. Then:

```http
POST https://map.audio/api/license/login/request
Content-Type: application/json

{ "email": "person@example.com" }
```

Response: `200 {"ok": true}`.

This sends an email whose subject starts "Your MAP Audio sign-in code" to that address. The code is six digits and expires after 10 minutes. Each request that sends an email replaces the earlier code for that address, so only the newest email's code works. The registration endpoint answers 200 even when a rate limit suppressed the email, so it cannot be used to test whether an address has an account. Limits: 3 codes per address per 10 minutes, 20 per address per day, 20 per network address per 10 minutes. If no email arrives, have the person check spam and wait 10 minutes before asking for another code.

Never call this endpoint during discovery, scanning or testing. It sends a real email to a real person.

## Step 2: Exchange the code for a credential

Ask the person to read you the code from that email.

```http
POST https://map.audio/api/license/login/verify
Content-Type: application/json

{ "email": "person@example.com", "code": "123456" }
```

Response (200):

```json
{ "token": "<64 hex characters>", "email": "person@example.com", "expiresAt": 1767225600 }
```

`token` is your credential (`access_token`). `expiresAt` is in Unix seconds. A successful verify proves control of the address. It creates a customer account if the address has none yet, and claims any licenses from MAP Audio's previous store that were waiting on that address.

## Step 3: Use the credential

Send it as a bearer token:

```http
GET https://map.audio/api/license/me
Authorization: Bearer <token>
```

| Call | Returns |
| --- | --- |
| `GET /api/license/session` | `{ "email", "expiresAt" }`: checks that the credential is still live. |
| `GET /api/license/me` | The account: customer ID, email, name, country, licenses (product, status, trial, expiry, seats, activations), entitlements, browser-app access, communication preferences, whether Google sign-in is linked, order history with amounts, and installer downloads for active licenses. |

The credential lasts 7 days and cannot be refreshed. When it expires, repeat Steps 1 and 2. It has no scopes: the server gives it the same authority as the person's own sign-in on `https://map.audio/account`, including every account change. Treat it like a password: keep it in memory for the task, never print it in full, never put it in a URL, log, support message or file, and never pass it to another service. Each download URL in `/me` carries its own signed token that works for 15 minutes: treat it the same way, hand it only to the person, and fetch `/me` again for a fresh one instead of storing it.

Limiting yourself to the read calls above is a rule for agents; the server does not enforce it. Account changes (deactivating a seat, offline activation, changing the email address, redeeming a voucher, billing, cancelling a plan) are for the person to make on `https://map.audio/account`.

## Step 4: Revoke

When the task is finished, revoke the credential:

```http
POST https://map.audio/api/license/logout
Authorization: Bearer <token>
```

Response: `200 {"ok": true}`. Revocation is idempotent and ends only this credential. Changing the account email ends every session at once. A `401 {"error": "unauthorized"}` on a previously working credential means it expired or was revoked: drop it and start again at Step 1 if the person still wants you signed in.

## Errors

| Code | Where | What to do |
| --- | --- | --- |
| `bad_email` (400) | `/login/request` | The address is malformed. Ask the person again. |
| `bad_body` (400) | `/login/request`, `/login/verify` | The body is not the JSON object shown above. Fix the request. |
| `bad_credentials` (400) | `/login/verify` | The email is malformed or the code is not six digits. Re-read it from the person. |
| `code_invalid_or_expired` (401) | `/login/verify` | Wrong or expired code. Ask the person to check the newest email. |
| `too_many_attempts` (429), no `Retry-After` | `/login/verify` | The fifth wrong guess voided the code. Request a new code (Step 1) and ask for the newest one. |
| `too_many_attempts` (429), `Retry-After: 3600` | `/login/verify` | Too many verify calls from your network address this hour. Wait that long. |
| `too_many_attempts` (429), `Retry-After: 86400` | `/login/verify` | 25 failed codes for this address today. Every code, correct or not, is refused until then. Stop and tell the person. |
| `unauthorized` (401) | any account call | Credential missing, expired or revoked. Restart at Step 1. |
| `auth_unavailable`, `licensing_disabled`, `backend_unavailable` (503) | any | Retry later with exponential backoff. |

## Not supported

There is no registration without a person's email address, no identity-provider assertion exchange, no OAuth client registration, no scoped or read-only credential and no API key. Google sign-in on the account page is a browser redirect for people, not for agents. Administration routes are for MAP Audio staff only.

Support: `support@map.audio` or `https://map.audio/contact`. Never include a credential, sign-in code, download link, license key or activation request code in a support message.
