REST API#

All Pulsora SDKs talk to a single endpoint: POST /api/ingest. You can call it directly from browsers (with public tokens) or from servers (with secret tokens).

  • Base URL: https://pulsora.co
  • Authentication: API tokens via header (X-API-Token) or JSON body (token)

Endpoint#

POST /api/ingest
Content-Type: application/json
X-API-Token: <token>
{
  "type": "pageview | event | identify | revenue",
  "token": "optional token if header missing",
  "data": {
    /* payload */
  }
}
  • Public tokens (pub_...) may send pageview, event, and identify.
  • Secret tokens (sec_...) may send all event types, including revenue.

Successful requests return 202 Accepted with { "success": true }. Events are queued asynchronously and processed by background workers.

Pageview Payload#

{
  "type": "pageview",
  "data": {
    "visitor_fingerprint": "fp_abc",
    "session_id": "sess_xyz",
    "url": "https://example.com/pricing",
    "path": "/pricing",
    "referrer": "https://google.com",
    "referrer_source": "google",
    "title": "Pricing",
    "locale": "en-US",
    "utm_source": "newsletter",
    "utm_medium": "email",
    "utm_campaign": "launch",
    "timestamp": 1714412000000
  }
}

Event Payload#

{
  "type": "event",
  "data": {
    "visitor_fingerprint": "fp_abc",
    "session_id": "sess_xyz",
    "event_name": "signup_submit",
    "event_data": {
      "plan": "pro",
      "form_variant": "modal"
    },
    "url": "https://example.com/signup",
    "path": "/signup",
    "timestamp": 1714412100000
  }
}

Identify Payload#

{
  "type": "identify",
  "data": {
    "visitor_fingerprint": "fp_abc",
    "session_id": "sess_xyz",
    "customer_id": "cus_123",
    "timestamp": 1714412150000
  }
}

Use identify after a user authenticates to connect anonymous sessions to customer records.

Revenue Payload#

See Revenue API Reference for full details. Revenue events require secret tokens.

Rate Limits#

  • Ingestion: 2,000 requests per hour per IP address.
  • Bursts exceeding the limit return 429 Too Many Requests with a Retry-After header (seconds). Client SDKs automatically respect this.

Testing the Endpoint#

curl https://pulsora.co/api/ingest \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Token: pub_123" \
  -d '{
    "type": "event",
    "data": {
      "visitor_fingerprint": "test_fingerprint",
      "session_id": "test_session",
      "event_name": "curl_test",
      "timestamp": 1714412200000
    }
  }'

Expect {"success":true} (202). In staging environments, inspect the queue or database to confirm ingestion.

Error Responses#

Status Body Description
400 { "message": "...validation..." } Missing required fields.
401 { "error": "Missing API token" | "Invalid API token" } Token missing or unrecognized.
403 { "error": "Revenue events require secret token" } Attempted to send revenue with public token.
429 { "error": "Rate limited" } (with Retry-After) Slow down & retry later.

See API Errors for a comprehensive list and troubleshooting steps.

Webhook Security#

When forwarding events from payment processors:

  • Verify signatures (Stripe, Paddle).
  • Respond promptly (<10s) to avoid retry storms.
  • Return 2xx only after revenue.track() succeeds.

SDK Compatibility#

  • @pulsora/core and @pulsora/react send pageview/event/identify payloads automatically.
  • @pulsora/revenue wraps the revenue payload with validation and retries.
  • Custom clients can use the same schema to interoperate.

Need TypeScript type definitions? See the Types reference →