Events API

POST /events/create

The single endpoint behind every Solary integration: track an event, resolve the shopper, and create a point transaction.

Request

http
POST /v1/events/create
Host: portal.solary.app/api
Content-Type: application/json
X-API-Key: YOUR_API_KEY

{
  "eventType": "purchase_completed",
  "email": "shopper@example.com",
  "firstname": "Jane",
  "lastname": "Doe",
  "pointsEarned": 2000,
  "type": "earn",
  "metadata": { "orderId": "12345" }
}

Headers

HeaderRequiredDescription
X-API-KeyYesYour company's API key. Identifies which company the event belongs to.
Content-TypeYesapplication/json

Body

FieldTypeRequiredDescription
eventTypestringYesFree-form event name, e.g. purchase_completed, signup_completed.
pointsEarnednumberYesHow many points to earn, redeem, or adjust.
emailstringOne of email/userIdIdentifies the shopper. If no Solary user exists yet for this email, one is created automatically and linked to your company.
userIdnumberOne of email/userIdThe shopper's internal Solary user id, if you already know it.
firstnamestringNoUsed only when a new user is created from email.
lastnamestringNoUsed only when a new user is created from email.
typeearn | redeem | adjustmentNoDefaults to earn.
metadataobjectNoArbitrary data attached to the transaction, e.g. an order id.

Identity resolution

You must provide either email or userId. Using email is the recommended path for platform integrations: Solary looks up the user by email, and if none exists yet, creates one automatically and links it to your company, no signup flow required on your end.

Response

On success, the endpoint returns the created point transaction.

201 Created
{
  "statusCode": 201,
  "data": {
    "id": 6,
    "createdAt": "2026-07-31T21:43:49.176Z",
    "updatedAt": "2026-07-31T21:43:49.176Z",
    "deletedAt": null,
    "userId": 4,
    "companyId": 1,
    "points": 2000,
    "type": "earn",
    "reason": "External event: purchase_completed",
    "source": "external_api",
    "status": "fulfilled",
    "metadata": { "eventType": "purchase_completed", "orderId": "12345" }
  }
}

On failure, it returns an error envelope with a human-readable message.

401 Unauthorized
{
  "errorId": "63e3001b-a1b3-456c-954a-c13ca97f06a9",
  "statusCode": 401,
  "timestamp": "2026-07-31T21:44:13.000Z",
  "path": "/v1/events/create",
  "data": { "errors": "Invalid or inactive API key" }
}

Status codes

StatusMeaning
201Transaction created.
400Missing or invalid fields, e.g. neither email nor userId provided.
401Missing, invalid, or revoked API key.
404userId was provided but doesn't match an existing user.
429 / 5xxRetry with backoff. All server SDKs do this automatically.

Ready to call this from your language of choice? See the server SDKs, or the platform integrations if you'd rather not write any code.