🎉 AdCP 3.0 is now GA — see what's new
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"
}
}Bootstrap a new organization member profile. This is the first-time onboarding call that has historically been reachable only through the AAO dashboard’s /onboarding form — making it a public REST surface lets registry API consumers (e.g. SSP/publisher integrations like the Scope3 storefront) drive the entire registration flow programmatically, without iframes or cross-domain redirects.
The caller must already be authenticated via OAuth (the user’s own WorkOS session). The profile is created on the caller’s primary WorkOS organization unless ?org= is supplied; in either case, the caller’s email domain must match corporate_domain (personal email domains like gmail.com / yahoo.com are rejected).
Idempotent on (organization_id, corporate_domain): re-posting for an organization that already has a profile returns 200 with the existing profile and a profile_already_exists warning, instead of 409.
Once the profile exists, follow up with POST /api/me/agents to register agents.
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.
Bearer token in the Authorization header. Two token types are accepted:
sk_...) issued via the dashboard. Org-scoped, long-lived, for server-to-server use./.well-known/oauth-authorization-server and the protected-resource metadata at /.well-known/oauth-protected-resource/api.WorkOS organization id to act on. Defaults to the caller's primary organization.
"org_01HXZAB123"
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.
Display name for the organization (shown on the member profile and in the registry catalog).
1 - 200"Acme Media"
Coarse classification of the member organization's role in the open ad ecosystem. Drives default verification badges and the member profile's display category.
adtech, agency, brand, publisher, data, ai, other 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.
"acme.com"
Annual revenue band, USD. Used for tier-based pricing and aggregated industry stats; not exposed on the public profile.
under_1m, 1m_5m, 5m_50m, 50m_250m, 250m_1b, 1b_plus 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.
"acme.com"
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).
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".
individual_academic A profile already exists for this organization; the existing profile is returned and no fields are mutated.
The member profile shape returned from POST /api/me/member-profile and GET /api/me/member-profile.
Show child attributes
Was this page helpful?