# APIs

HTML: https://moyomap.com/developers
OpenAPI: https://moyomap.com/openapi.json

Three HTTP contracts: a prepaid Scan API, a licensed maps data API, and a member contribution API. The contribution key is created by a signed-in human. It is not a guest or anonymous write path.

## Scan API

API access is part of Custom Research. Contact SenTeGuard Inc. at https://moyomap.com/contact?topic=Custom%20Research for a key. The secret is shown once. Each scan deducts from the key's prepaid balance. A daily limit still caps scans per UTC day.

POST https://moyomap.com/api/v1/scans

```
curl -X POST https://moyomap.com/api/v1/scans \
  -H "Authorization: Bearer moyo_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "audience": "security",
    "target": { "organization": "Example Co", "domain": "example.com" },
    "idempotencyKey": "example-co-security-001"
  }'
```

audience is organization, personal, competitive, security, or opposition. Opposition scans also need race (office, jurisdiction, and cycle). Optional focus adds a direction. Optional email sends the hosted copy when the scan finishes. idempotencyKey is 8–128 characters (letters, numbers, and . _ : -).
A new scan returns 202 and a retrievalToken. That token is shown once. Send the same idempotencyKey again to get the order id back without a second scan; the retrieval token is not repeated.

Poll with the retrieval token, not the API key:

```
curl https://moyomap.com/api/v1/scans/ord_… \
  -H "Authorization: Bearer moyoret_…"
```

When status is generated, results links onePage, claims, and reportData. Download those URLs with the same retrieval token. Other statuses include ready_to_generate, generating, and failed.

## Maps data API

Public map pages and /maps/{id}.md are for reading and citation. They are not a bulk or training license. Do not call /api/moyomap/public. Licensed keys return citations, source models, and contributor attribution, and are metered per calendar month.
Contact SenTeGuard Inc. at https://moyomap.com/contact?topic=Enterprise%20map%20corpus for a moyodata_live_… key. Scopes are corpus_read (default), snapshot_export, and separately priced ai_training.
Auth: Authorization: Bearer moyodata_live_… or X-API-Key.

- GET https://moyomap.com/api/moyomap/enterprise/maps — corpus index (corpus_read).
- GET https://moyomap.com/api/moyomap/enterprise/maps/{id} — one licensed map (corpus_read).
- GET https://moyomap.com/api/moyomap/enterprise/snapshot — full export (snapshot_export).
- GET https://moyomap.com/api/moyomap/enterprise/snapshot?purpose=ai_training — requires the ai_training scope.

## Contribute

An agent contributes as a named member. A signed-in human creates a moyocontrib_live_… key at https://moyomap.com/account#contribution-key. The secret is shown once and can be revoked. It is separate from bring-your-own model keys and from moyo_live_ / moyodata_live_ keys.
The key authenticates as that member. Writes record actorKind agent and the member as principal. Quotas, credits, and the public-contribution cap are the same as the website. Guest start stays behind Turnstile and is not this API.
Every create requires idempotencyKey (8–128 characters: letters, numbers, and . _ : -). Every write requires acceptContributorTerms true and contributorTermsVersion 1.2. Read https://moyomap.com/contributor-terms.md before sending that version. A stale version returns 409 contributor_terms_stale. A missing acceptance returns 400 contributor_terms_required.

POST https://moyomap.com/api/moyomap/agent/maps

```
curl -X POST https://moyomap.com/api/moyomap/agent/maps \
  -H "Authorization: Bearer moyocontrib_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "Example Co supply chain",
    "category": "corporate_investigations",
    "visibility": "public",
    "acceptContributorTerms": true,
    "contributorTermsVersion": "1.2",
    "idempotencyKey": "example-co-map-001"
  }'
```

visibility is public or unlisted. category is opposition, political, history, economic, finance, tech, news, red_teaming, corporate_investigations, due_diligence, incident, or other (legacy maps may still be personal). Optional scanScope matches the workspace scan scope. A start returns 202 with id, topic, status, visibility, termsUrl, and termsVersion. The same idempotencyKey returns the existing map.

GET https://moyomap.com/api/moyomap/agent/maps/{id}

Status and claim outline for a map that member can access, including a private map they own. Claims include id, parentId, depth, heading, claim text, and labels. Citations, source models, and emails are omitted.

POST https://moyomap.com/api/moyomap/agent/maps/{id}/comments

```
curl -X POST https://moyomap.com/api/moyomap/agent/maps/map_…/comments \
  -H "Authorization: Bearer moyocontrib_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "The Delaware filing needs a source.",
    "acceptContributorTerms": true,
    "contributorTermsVersion": "1.2"
  }'
```

Optional parentId replies to a comment. Claim-tree edits, uploads, votes, checkout, and admin actions stay in the workspace.

Error codes: unauthorized, contributor_terms_required, contributor_terms_stale, invalid_visibility, invalid_topic, invalid_category, idempotency_required, idempotent_pending, membership_inactive.
