Seedy Pea

HTTP API

The public HTTP API accepts JSON and returns JSON. Browser-callable routes use project write-key authentication and origin checks.

Base URL:

https://app.seedy-pea.com

Common request fields:

Field Description
project_id Project id, for example proj_....
write_key Project write key.
anonymous_id Visitor id for anonymous profile routing.
profile_ref Optional explicit profile reference on profile, delete, and decision routes.

If a project has an origin configured, the request Origin header must match it.

POST /v1/events

Append a customer event.

POST /v1/events
Content-Type: application/json
Origin: https://example.com
{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123",
  "type": "PageViewed",
  "detail": {
    "path": "/pricing"
  }
}

Response:

{
  "ok": true,
  "event_id": "evt_...",
  "profile_ref": "anonymous:proj_...:visitor_123"
}

Event types must match:

^[A-Za-z][A-Za-z0-9_.]{0,62}$

Most sp.* event types are reserved for trusted substrate machinery. Customer-allowed sp.* types are currently sp.consent.granted and sp.consent.revoked.

segment.<name>.entered and segment.<name>.exited are also reserved.

POST /v1/scores

Append an external model score as sp.model.scored.

{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123",
  "model_name": "founder_offer_lookalike",
  "model_version": 4,
  "target": "founder_offer_capture_goal",
  "score": 0.73,
  "reasons": [
    { "contributor": "neighbors", "weight": 0.73 }
  ]
}

Response:

{
  "ok": true,
  "event_id": "evt_...",
  "scored_at": "2026-06-06T16:00:00.000Z",
  "score": {
    "model_name": "founder_offer_lookalike",
    "score": 0.73,
    "model_version": 4,
    "target": "founder_offer_capture_goal"
  }
}

model_name must be declared in the project's scoring topology. target and model_version default from that declaration when omitted. scored_at is optional, but must be an ISO timestamp when provided.

POST /v1/profile

Fetch the current profile fold for an anonymous id or explicit profile ref.

{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123"
}

Response:

{
  "ok": true,
  "profile_ref": "anonymous:proj_...:visitor_123",
  "fold": {
    "profile_ref": "anonymous:proj_...:visitor_123",
    "pageview_count": 3
  },
  "segments": [
    { "segment_name": "all" }
  ],
  "tactics": {},
  "imported_facts": []
}

POST /v1/profile/delete

Erase the profile addressed by anonymous_id or profile_ref.

{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123"
}

Response:

{
  "ok": true,
  "profile_ref": "anonymous:proj_...:visitor_123",
  "vault_shredded": true,
  "profile_destroyed": true,
  "receipt_event_id": "evt_..."
}

The seedypea-client forget() helper calls this route directly in direct mode. In edge mode, it calls your same-origin /sp/profile/delete proxy.

POST /v1/decide

Ask Seedy Pea what to show on a surface. This route can create experiment assignment facts.

{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123",
  "surface": "homepage_hero"
}

Response:

{
  "ok": true,
  "profile_ref": "anonymous:proj_...:visitor_123",
  "surface": "homepage_hero",
  "experiments": {
    "homepage_hero_copy": {
      "variant": "receipts_first"
    }
  }
}

POST /v1/experiment/expose

Record that an assigned variant was actually shown.

{
  "project_id": "proj_...",
  "write_key": "wk_...",
  "anonymous_id": "visitor_123",
  "experiment_name": "homepage_hero_copy",
  "surface": "homepage_hero"
}

Response is the substrate exposure result from the profile.

Assignment and exposure are separate facts. Calling /v1/decide does not imply exposure.