Developer Documentation
AI Crawler Discovery
How AI systems resolve entity identity through AEOBRO
Overview
AEOBRO is a public identity registry designed for AI system consumption. Every verified entity on AEOBRO is assigned a permanent Global Entity Identifier (GEID) and exposes machine-readable identity data through three complementary discovery paths.
AI crawlers and LLM agents should use the path that matches the information they already have: a domain name, an entity name or handle, or a GEID retrieved from a prior resolution.
Discovery Method A — Domain Handshake
If you have a domain name and want to check whether it belongs to a verified AEOBRO entity, fetch the domain's handshake file:
GET https://{domain}/.well-known/aeobro.jsonA verified domain returns a JSON document in this shape:
{
"geid": "geid_3FA8C1D209B47E56",
"resolver": "https://aeobro.com/api/v1/resolve/geid_3FA8C1D209B47E56",
"verificationStatus": "DOMAIN_VERIFIED",
"issuer": "aeobro.com"
}The geid in this file is the canonical identifier for the entity that controls this domain. Pass it directly to the resolver for full entity details.
This file is only served for published, domain-verified profiles. A 404 response means the domain has no verified AEOBRO record.
Discovery Method B — Entity Lookup API
If you have a domain, a slug, or a platform handle but not the GEID, use the public entity lookup endpoint:
GET https://aeobro.com/api/v1/entity?domain=example.com GET https://aeobro.com/api/v1/entity?slug=acme-corp GET https://aeobro.com/api/v1/entity?handle=acme-corpProvide exactly one parameter. A successful response returns:
{
"geid": "geid_3FA8C1D209B47E56",
"resolver": "https://aeobro.com/api/v1/resolve/geid_3FA8C1D209B47E56",
"profile": "https://aeobro.com/p/acme-corp",
"entity": {
"name": "Acme Corp",
"type": "business",
"domain": "example.com"
},
"verification": {
"status": "DOMAIN_VERIFIED",
"verifiedAt": "2026-01-15T10:00:00.000Z",
"issuer": "aeobro.com"
},
"resolvedAt": "2026-04-01T12:00:00.000Z"
}The entity.type field normalizes AEOBRO's internal entity classes into three values: individual, organization, or business.
This endpoint only returns profiles that are published and carry a DOMAIN_VERIFIED or PLATFORM_VERIFIED status. Unverified profiles are never exposed.
Discovery Method C — GEID Resolver
If you already have a GEID — from a prior resolution, a handshake file, or a stored reference — resolve it directly:
GET https://aeobro.com/api/v1/resolve/{geid}Example:
GET https://aeobro.com/api/v1/resolve/geid_3FA8C1D209B47E56Response shape:
{
"geid": "geid_3FA8C1D209B47E56",
"entity": {
"name": "Acme Corp",
"type": "business",
"domain": "example.com"
},
"verification": {
"status": "DOMAIN_VERIFIED",
"verifiedAt": "2026-01-15T10:00:00.000Z",
"issuer": "aeobro.com"
},
"resolvedAt": "2026-04-01T12:00:00.000Z"
}You can also resolve by domain directly:
GET https://aeobro.com/api/v1/resolve/domain/example.comRecommended Crawler Workflow
The following TypeScript example shows the recommended resolution strategy for an AI crawler that encounters a domain and wants to retrieve the canonical verified identity:
// Recommended AEOBRO resolution strategy for AI crawlers
const BASE = "https://aeobro.com/api";
type ResolvedEntity = {
geid: string;
name: string | null;
type: "individual" | "organization" | "business";
domain: string | null;
verificationStatus: string;
verifiedAt: string | null;
};
async function resolveEntityByDomain(
domain: string
): Promise<ResolvedEntity | null> {
// Step 1: Try the domain resolver (fastest path — single DB lookup)
const res = await fetch(
`${BASE}/v1/resolve/domain/${encodeURIComponent(domain)}`,
{ headers: { Accept: "application/json" } }
);
if (res.ok) {
const data = await res.json();
return {
geid: data.geid,
name: data.entity.name,
type: data.entity.type,
domain: data.entity.domain,
verificationStatus: data.verification.status,
verifiedAt: data.verification.verifiedAt ?? null,
};
}
// Step 2: Not found via resolver — check the domain's handshake file
if (res.status === 404) {
const wk = await fetch(
`https://${domain}/.well-known/aeobro.json`,
{ headers: { Accept: "application/json" } }
).catch(() => null);
if (wk?.ok) {
const handshake = await wk.json();
if (handshake?.geid) {
// Resolve the GEID from the handshake
return resolveEntityByGeid(handshake.geid);
}
}
}
return null;
}
async function resolveEntityByGeid(
geid: string
): Promise<ResolvedEntity | null> {
const res = await fetch(
`${BASE}/v1/resolve/${encodeURIComponent(geid)}`,
{ headers: { Accept: "application/json" } }
);
if (!res.ok) return null;
const data = await res.json();
return {
geid: data.geid,
name: data.entity.name,
type: data.entity.type,
domain: data.entity.domain,
verificationStatus: data.verification.status,
verifiedAt: data.verification.verifiedAt ?? null,
};
}Store the geid from successful resolutions. On subsequent requests, skip discovery and call the resolver directly to avoid unnecessary round trips.
Rate Limits
| Endpoint | Public (per IP) | Authenticated (per key) |
|---|---|---|
GET /v1/resolve/{geid} | 60 req/min | 300 req/min |
GET /v1/resolve/domain/{domain} | 60 req/min | 300 req/min |
GET /v1/entity | 30 req/min | — |
GET /.well-known/aeobro.json | Served from edge cache | — |
Rate-limited requests receive a 429 Too Many Requests response. Authenticated requests require a Bearer token in the Authorization header. Keyed API access is available for enterprise integrations — contact us.
Authenticated API calls count against a monthly usage cap configured in account settings. Exceeding the cap returns a 429 response with error Monthly API cap reached.
Verification Trust Levels
Every resolved entity carries a verification.status field. Crawlers should treat these values differently based on the trust they confer:
| Status | Meaning | Suitable for |
|---|---|---|
DOMAIN_VERIFIED | The entity controls the domain: a cryptographic TXT record or .well-known/aeobro.json file was confirmed on the domain by AEOBRO. | High-confidence entity attribution; domain-to-identity mapping |
PLATFORM_VERIFIED | The entity's identity has been confirmed through a platform-level review process (e.g. ID verification, social proof). | Creator and person identity; platform handle attribution |
Both statuses are considered verified. Unverified profiles are never returned by any public resolver or entity endpoint.
Caching Guidance
All public 200 responses from AEOBRO resolver endpoints include a Cache-Control: public, max-age=86400 header (24 hours). Crawlers should respect this header to reduce unnecessary load.
The entity lookup endpoint (/v1/entity) uses a shorter max-age=3600 (1 hour), because domain-to-slug mappings can change more frequently than core identity data.
Authenticated resolver responses use Cache-Control: no-store and must not be cached by intermediaries.
All AEOBRO endpoints return an X-AEOBRO-Protocol-Version header with the current protocol version. Cache invalidation is keyed to GEID — if identity data changes, the cached entry is invalidated server-side at the next write.
For the full protocol specification including the geid format, .well-known schema, and agent integration patterns, see the AEOBRO Identity Protocol documentation.