Formo Events API

Event ingestion API (events.formo.so)

GitHub OpenAPI

Operations 1

POST /v0/raw_events Ingest events #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/formo-so:formo-so-events-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

formo-so-events-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Formo Public Events API
  description: 'REST API for managing Formo projects, analytics, alerts, boards, charts, contracts, segments, and AI chat.


    **Auth.** Every endpoint on `api.formo.so` requires a workspace API key with the appropriate scopes (see `x-api-scopes`). The one exception is `POST /v0/raw_events`, which runs on `events.formo.so` and authenticates with the project SDK write key instead.


    **Response shape.** Successful responses return the resource directly (or `{ data: [...], total, page, size, has_more }` for paginated lists). HTTP status carries success/failure; there is no envelope wrapping success bodies.


    **Errors.** Non-2xx responses from `api.formo.so` use the `Error` envelope, with two exceptions: some rate-limit rejections reply in plain text, and `POST /v0/raw_events` returns a plain `{ "error": "..." }` object. Treat the HTTP status as authoritative and parse defensively: `{ error: { code, message, doc_url, param?, details? } }`. Branch on the machine-readable `code` (see `ErrorCode` enum) and follow `doc_url` to the matching section of the errors reference.


    **Idempotency.** Pass an `Idempotency-Key` header on write requests to alerts, boards, charts, contracts, segments, and import to make retries safe; the response is cached for 24 h and replayed on duplicate keys. Profile writes and `POST /v0/query` do not support it.'
  version: 0.1.0
  contact:
    name: Formo
    url: https://formo.so
servers:
- url: https://api.formo.so
  description: API Server (boards, alerts, contracts, segments, profiles, query, import)
- url: https://events.formo.so
  description: Events Server (event ingestion)
security:
- WorkspaceApiKey: []
tags:
- name: Events
  description: Event ingestion API (events.formo.so)
paths:
  /v0/raw_events:
    post:
      operationId: ingestEvents
      summary: Ingest events
      description: Send analytics events to Formo. This endpoint runs on events.formo.so (not api.formo.so). Authenticate with your project's SDK write key.
      tags:
      - Events
      servers:
      - url: https://events.formo.so
      security:
      - SdkWriteKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/Event'
            examples:
              pageView:
                summary: Track a page view
                value:
                - type: page
                  channel: web
                  version: '1'
                  anonymous_id: e397c4e7-5f0a-45d6-a06c-f34a809d8b82
                  user_id: ''
                  address: ''
                  event: ''
                  context:
                    user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
                    locale: en-US
                    timezone: America/Los_Angeles
                    location: US
                    ref: ''
                    referrer: ''
                    utm_campaign: ''
                    utm_content: ''
                    utm_medium: ''
                    utm_source: ''
                    utm_term: ''
                    page_title: Dashboard | MyApp
                    page_url: https://myapp.com/swap/ethereum#/swap
                    page_path: /swap/ethereum
                    library_name: Formo Web SDK
                    library_version: 1.27.0
                    browser: chrome
                    device: desktop
                    os: Windows
                    screen_width: 1280
                    screen_height: 720
                    screen_density: 1.5
                    viewport_width: 1280
                    viewport_height: 604
                  properties:
                    url: https://myapp.com/swap/ethereum#/swap
                    path: /swap/ethereum
                    hash: '#/swap'
                    query: ''
                  original_timestamp: '2026-04-28T02:08:30.000Z'
                  sent_at: '2026-04-28T02:09:00.000Z'
                  message_id: 263434374239d12b797bf571c6045d6f9f9000a70f19f94d75ca485536606b27
              walletConnect:
                summary: Track a wallet connection
                value:
                - type: connect
                  channel: web
                  version: '1'
                  anonymous_id: 66b81795-cf59-43d1-80ab-ef48098b6e06
                  user_id: ''
                  address: '0xA39260F25D6ebBEAE4595977bDE410623A96E7Af'
                  event: ''
                  context:
                    user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
                    locale: en-US
                    timezone: Europe/London
                    location: GB
                    page_title: MyApp - Swap & Bridge
                    page_url: https://myapp.com/earn/positions
                    library_name: Formo Web SDK
                    library_version: 1.27.0
                    browser: chrome
                    device: desktop
                    os: Windows
                  properties:
                    rdns: io.metamask
                    chain_id: 43114
                    provider_name: MetaMask
                  original_timestamp: '2026-04-27T20:04:54.000Z'
                  sent_at: '2026-04-27T20:05:00.000Z'
                  message_id: b0a1dc19c494df191e2cb0c56460f7472113e5858440b3d4f3798a070265f631
              trackEvent:
                summary: Track a custom event
                value:
                - type: track
                  channel: web
                  version: '1'
                  anonymous_id: 66b81795-cf59-43d1-80ab-ef48098b6e06
                  address: '0xA39260F25D6ebBEAE4595977bDE410623A96E7Af'
                  event: Chain Switched
                  context:
                    user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
                    locale: en-US
                    timezone: Europe/London
                    location: GB
                    page_url: https://myapp.com/swap
                    library_name: Formo Web SDK
                    library_version: 1.27.0
                    browser: chrome
                    device: desktop
                    os: Windows
                  properties:
                    old_network: Arbitrum
                    new_network: BNB Chain
                  original_timestamp: '2026-04-27T23:05:38.000Z'
                  sent_at: '2026-04-27T23:05:42.000Z'
                  message_id: f4b2e8c1a59d3e7f6c8b9a02d5e4f1c3b8a7e6d5c4b3a291807e6d5c4b3a2918
              identify:
                summary: Identify a wallet
                value:
                - type: identify
                  channel: web
                  version: '1'
                  anonymous_id: 66b81795-cf59-43d1-80ab-ef48098b6e06
                  user_id: usr_42a91c2b
                  address: '0xA39260F25D6ebBEAE4595977bDE410623A96E7Af'
                  event: null
                  context:
                    library_name: Formo Web SDK
                    library_version: 1.27.0
                    user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
                    locale: en-US
                    timezone: Europe/London
                    location: GB
                    page_url: https://myapp.com/dashboard
                    browser: chrome
                    device: desktop
                    os: Windows
                  properties:
                    rdns: io.metamask
                    provider_name: MetaMask
                    email: alice@example.com
                    display_name: alice.eth
                  original_timestamp: '2026-04-27T20:05:10.000Z'
                  sent_at: '2026-04-27T20:05:11.000Z'
                  message_id: 7e2a4b1c8d3f6e9a0b5c2d1e4f7a8b6c9d0e3f2a1b4c5d6e7f8a9b0c1d2e3f4a
              transaction:
                summary: Track an onchain transaction
                value:
                - type: transaction
                  channel: web
                  version: '1'
                  anonymous_id: 66b81795-cf59-43d1-80ab-ef48098b6e06
                  user_id: ''
                  address: '0xA39260F25D6ebBEAE4595977bDE410623A96E7Af'
                  event: ''
                  context:
                    library_name: Formo Web SDK
                    library_version: 1.27.0
                    user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
                    locale: en-US
                    timezone: Europe/London
                    location: GB
                    page_url: https://myapp.com/swap
                    browser: chrome
                    device: desktop
                    os: Windows
                  properties:
                    status: confirmed
                    chain_id: 1
                    to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
                    value: '0'
                    transaction_hash: '0x6f4c1f2c3a8b9e0d1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e'
                    function_name: transfer
                    function_args:
                      to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
                      amount: '1000000000'
                    revenue: 250.5
                    currency: usd
                  original_timestamp: '2026-04-27T22:14:03.000Z'
                  sent_at: '2026-04-27T22:14:04.000Z'
                  message_id: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
      responses:
        '200':
          description: Batch accepted. The body carries an ingestion summary when one is available, otherwise `{}`.
          content:
            application/json:
              schema:
                type: object
              example: {}
        '202':
          description: 'Batch accepted for asynchronous processing. Returns `{ "queued": true }` when the batch was buffered for retry, an ingestion summary when one is available, otherwise `{}`.'
          content:
            application/json:
              schema:
                type: object
              example:
                queued: true
        '400':
          description: The request body is missing. A body that is present but not valid JSON returns 500 instead.
          content:
            application/json:
              schema:
                type: object
              example:
                error: Invalid request body
        '401':
          description: The request could not be authenticated.
          content:
            application/json:
              schema:
                type: object
              example:
                error: Unauthorized
        '403':
          description: Missing or invalid SDK write key. The body for this status is not the shape shown here.
          content:
            application/json:
              schema:
                type: object
              example:
                Message: User is not authorized to access this resource with an explicit deny
        '500':
          description: The batch could not be ingested, or the request body was not valid JSON.
          content:
            application/json:
              schema:
                type: object
              example:
                error: Internal Server Error
components:
  schemas:
    Event:
      type: object
      description: A single analytics event
      required:
      - type
      - anonymous_id
      - version
      - channel
      properties:
        type:
          type: string
          enum:
          - page
          - connect
          - disconnect
          - chain
          - signature
          - transaction
          - track
          - detect
          - identify
        channel:
          type: string
          enum:
          - web
          - mobile
          - server
          - api
          - import
          description: Source of the event. The Formo Web SDK uses `web`; mobile SDK uses `mobile`; server SDK uses `server`. Use `api` for direct HTTP submissions and `import` for backfills.
        version:
          type: string
          description: SDK schema version. Web SDK 1.x emits `1`; legacy clients emit `0`.
          example: '1'
        anonymous_id:
          type: string
          description: Anonymous visitor identifier
        user_id:
          type: string
          nullable: true
          description: Identified user ID
        address:
          type: string
          nullable: true
          description: Wallet address
        event:
          type: string
          nullable: true
          description: Event name (for track events)
        context:
          $ref: '#/components/schemas/EventContext'
        properties:
          $ref: '#/components/schemas/EventProperties'
        original_timestamp:
          type: string
          format: date-time
        sent_at:
          type: string
          format: date-time
        message_id:
          type: string
          description: Unique ID for deduplication. Optional; a UUID is generated server-side when omitted.
    EventProperties:
      type: object
      description: Event-specific properties. Can contain any key-value pairs relevant to the event.
      additionalProperties: true
    EventContext:
      type: object
      description: Contextual information about the event environment
      properties:
        user_agent:
          type: string
        locale:
          type: string
          description: e.g. en-US
        timezone:
          type: string
          description: e.g. America/New_York
        page_url:
          type: string
        page_path:
          type: string
        page_title:
          type: string
        page_query:
          type: string
        page_hash:
          type: string
        referrer_url:
          type: string
        referrer:
          type: string
        ref:
          type: string
        utm_source:
          type: string
        utm_medium:
          type: string
        utm_campaign:
          type: string
        utm_term:
          type: string
        utm_content:
          type: string
        browser:
          type: string
        device:
          type: string
          enum:
          - desktop
          - mobile
          - tablet
        os:
          type: string
        screen_width:
          type: integer
        screen_height:
          type: integer
        screen_density:
          type: number
          description: Pixel density of the device screen (devicePixelRatio)
        viewport_width:
          type: integer
          description: Width of the browser viewport in pixels
        viewport_height:
          type: integer
          description: Height of the browser viewport in pixels
        location:
          type: string
          description: Geographic location country code (e.g., US, NG)
        library_name:
          type: string
        library_version:
          type: string
  securitySchemes:
    WorkspaceApiKey:
      type: http
      scheme: bearer
      description: Workspace API key (e.g. `formo_xxx`). Create one in the Formo dashboard under Team Settings > API.
    X402Payment:
      type: apiKey
      in: header
      name: X-PAYMENT
      description: x402 payment payload generated after the gateway returns a 402 challenge.
    MPPPayment:
      type: apiKey
      in: header
      name: Authorization
      description: MPP payment authorization header, formatted as `Payment <payload>`, generated after the gateway returns a 402 challenge.
    SdkWriteKey:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Project SDK write key (a JWT), sent as `Authorization: Bearer <write key>`. This is NOT the `formo_...` workspace API key used on api.formo.so. Find it in the Formo dashboard under the project’s settings.'
x-api-scopes:
  description: API key scopes control access to endpoints. Create keys with the required scopes in Team Settings > API.
  scopes:
    alerts:read: List and get alerts
    alerts:write: Create, update, delete alerts (requires alerts:read)
    boards:read: List and get boards and charts
    boards:write: Create, update, delete boards and charts (requires boards:read)
    contracts:read: List contracts
    contracts:write: Create, update, delete contracts (requires contracts:read)
    segments:read: List segments
    segments:write: Create and delete segments (requires segments:read)
    profiles:read: Search and get wallet profiles
    profiles:write: Update wallet properties, manage labels, and import addresses (requires profiles:read)
    query:read: Execute SQL analytics queries and read pre-built analytics endpoints (KPIs, top pages, lifecycle, retention, revenue, etc.)