Skip to main content
API reference

For the brave.

No exercises and no congratulations at the end — just the endpoints, in order, with examples that actually run.

The API is hosted at api.goatech.ai during the rebrand to Sheepit. Both hosts will be aliased once DNS cuts over.

Base URL
https://api.goatech.ai
Auth header
Authorization: Bearer lp_…
Success envelope
{ "data": { … } }
Error envelope
{ "error": { "code", "message" } }
Rate limit
100 req/min per key (defaults)
Content type
application/json
Auth

API key types

Sheepit uses bearer tokens. Every key is prefixed by what it can do, so you can tell at a glance whether you've checked the right one into the right place.

  • lp_pub_…Publishable

    Client-side SDK key. Safe to ship in browser and mobile bundles. Can read /v1/config and post events. Cannot touch admin routes.

  • lp_sec_…Secret

    Server-side SDK key with full project access. Used by server SDKs. Never embed client-side.

  • lp_dev_…Dev / CLI

    Read-only access to schemas and definitions. Powers @goatech/cli codegen. Safe for dev shell + CI secrets, not client bundles.

Send the key as Authorization: Bearer <key>. Every request that needs auth needs this header.

Your first request

Send one event

Paste this into a terminal. Replace the key. If the response is { "data": { "accepted": 1 } }, you're done — the event is in the dashboard.

curl -X POST https://api.goatech.ai/v1/ingest \
  -H "Authorization: Bearer lp_pub_xxx_…" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [{
      "event": "signup",
      "anonymous_id": "anon-abc",
      "properties": { "source": "docs" },
      "timestamp": "2026-05-26T18:00:00Z"
    }]
  }'

That's the whole loop. Everything else in this page is a variation on the same shape.

Resources

Endpoints

The endpoints the SDKs call today. New ones land here as we ship them.

POST/v1/devices/registerpublishable key

Register an anonymous device on app boot. Returns a device ID you store locally.

POST/v1/devices/:deviceId/identifypublishable key

Attach a user ID to a previously-registered device.

GET/v1/configpublishable key

Snapshot of all flags + experiment assignments for the current device / user. Cache it; refresh on app foreground.

POST/v1/ingestpublishable key

Send one or many events in a single batch. Fire-and-forget; client SDKs queue and retry.

POST/v1/crashes/reportpublishable key

Submit a crash report. Used by the mobile SDKs.

POST/v1/performance/ingestpublishable key

Batched performance metrics (startup time, frame drops, ANR, network spans).

Errors

What can go wrong

All errors come back as { "error": { "code", "message" } }. The code is stable; the message is human-readable.

StatusCodeMeaning
400invalid_inputBody didn't parse, or required fields were missing.
401unauthorizedMissing or malformed Authorization header.
403forbiddenKey is real but doesn't have permission for this route (e.g. pub key on admin route).
404not_foundResource doesn't exist or isn't visible to your project.
409conflictIdempotency or uniqueness conflict (e.g. event_id already ingested).
429rate_limitedYou're sending too fast. Back off and retry with jitter.
5xxserver_errorOur fault. SDKs already retry; if it persists, email us.

Missing an endpoint? More are landing here as we ship them.

Ask us about one →