Skip to main content
POST
/
api
/
me
/
member-profile
Create my member profile
curl --request POST \
  --url https://agenticadvertising.org/api/me/member-profile \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "organization_name": "Acme Media",
  "company_type": "adtech",
  "corporate_domain": "acme.com",
  "revenue_tier": "under_1m",
  "primary_brand_domain": "acme.com",
  "marketing_opt_in": false,
  "membership_tier": "individual_academic"
}
'
{
  "profile": {
    "organization_id": "org_01HXZAB123",
    "organization_name": "Acme Media",
    "company_type": "adtech",
    "corporate_domain": "<string>",
    "created_at": "2023-11-07T05:31:56Z",
    "agents": [
      {
        "url": "https://agent.example.com/mcp",
        "visibility": "private",
        "name": "<string>",
        "type": "brand",
        "health_check_url": "<string>"
      }
    ],
    "revenue_tier": "under_1m",
    "primary_brand_domain": "<string>",
    "membership_tier": "individual_professional"
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt

Use this file to discover all available pages before exploring further.

Authorizations

Authorization
string
header
required

Bearer token in the Authorization header. Two token types are accepted:

  • Organization API key (sk_...) issued via the dashboard. Org-scoped, long-lived, for server-to-server use.
  • User JWT obtained via the OAuth 2.1 authorization code flow with PKCE. User-scoped, short-lived. Discover the authorization server at /.well-known/oauth-authorization-server and the protected-resource metadata at /.well-known/oauth-protected-resource/api.

Query Parameters

org
string

WorkOS organization id to act on. Defaults to the caller's primary organization.

Example:

"org_01HXZAB123"

Body

application/json

Request body for POST /api/me/member-profile. Creates the organization member profile that backs the per-agent registry endpoints. Fails with 403 if the caller's email domain does not match corporate_domain.

Org metadata fields (organization_name, company_type, revenue_tier, membership_tier) are written to the organization row only when the field is currently null. If a value is already set (e.g. an admin curated it via the dashboard), the body value is silently ignored and the response surfaces a metadata_unchanged warning naming the affected API fields. This prevents a programmatic bootstrap from clobbering admin-curated metadata on subsequent calls.

If corporate_domain is already linked to a different organization (e.g. an earlier bootstrap on a sibling org), the profile is still created on the requested organization but the domain is not attached, and the response surfaces a domain_already_claimed warning naming the affected domain. Registry surfaces that depend on the verified domain (brand.json publish, brand resolution) will not reflect the profile until support resolves the conflict.

The caller's Terms-of-Service and Privacy-Policy acceptance is recorded server-side from the request context (X-Forwarded-For IP + User-Agent), against the current published agreement version, against the target organization. There is no opt-out — calling this endpoint is the consent.

The endpoint is rate-limited at 15 failed attempts per hour per user — successful calls do not count. The legacy display_name+slug body shape (used by the AAO dashboard profile-edit form) bypasses the rate limit and the bootstrap flow entirely; that shape continues to return 409 on conflict and writes the full profile body as before.

organization_name
string
required

Display name for the organization (shown on the member profile and in the registry catalog).

Required string length: 1 - 200
Example:

"Acme Media"

company_type
enum<string>
required

Coarse classification of the member organization's role in the open ad ecosystem. Drives default verification badges and the member profile's display category.

Available options:
adtech,
agency,
brand,
publisher,
data,
ai,
other
corporate_domain
string
required

Canonical domain for the organization. Must match the email domain of the authenticated caller (e.g. an @acme.com user can only create a profile for acme.com). Personal email domains (gmail.com, yahoo.com, etc.) are rejected — register as an individual via the dashboard onboarding instead.

Example:

"acme.com"

revenue_tier
enum<string>

Annual revenue band, USD. Used for tier-based pricing and aggregated industry stats; not exposed on the public profile.

Available options:
under_1m,
1m_5m,
5m_50m,
50m_250m,
250m_1b,
1b_plus
primary_brand_domain
string

The brand domain whose brand.json will reflect this profile's public agents. Optional at creation; required before any agent can be set to visibility: public.

Example:

"acme.com"

marketing_opt_in
boolean
default:false

Whether the caller agreed to receive AAO marketing communications. Independent of Terms of Service consent (which is required and recorded server-side from the request context).

membership_tier
enum<string>

Initial membership tier. Only individual_academic (the free Explorer baseline) is accepted on this endpoint — paid tiers must come through a Stripe checkout session via the AAO /membership dashboard, and the webhook stamps the paid tier on the org row. Sending a paid tier value here returns 400 "Paid tier requires checkout".

Available options:
individual_academic

Response

A profile already exists for this organization; the existing profile is returned and no fields are mutated.

profile
object
required

The member profile shape returned from POST /api/me/member-profile and GET /api/me/member-profile.