---
title: "Track event"
full: true
_openapi:
  method: POST
  toc: []
  structuredData:
    headings: []
    contents:
      - content: "Fires a workflow-only custom event: validates properties and enrolls matching automations. Pass email to create the contact if it does not exist. Not related to outbound webhooks."
_apiData:
  document: "https://reloop.sh/api/workflow/openapi/json"
  operationData: [{"path":"/api/workflow/v1/events/track","method":"post"}]
  parameterList: [{"name":"event","type":"string","required":true,"description":"The event key, e.g. user.signed_up. The \"trigger.\" prefix is optional.","location":"body","minLength":1,"maxLength":128},{"name":"contactId","type":"string","required":false,"description":"Contact the event happened to. Pass this or email.","location":"body"},{"name":"email","type":"string","required":false,"description":"Contact email. Creates the contact if it does not exist yet.","location":"body"},{"name":"firstName","type":"string","required":false,"description":"Used when the contact is created from email","location":"body","maxLength":255},{"name":"lastName","type":"string","required":false,"description":"Used when the contact is created from email","location":"body","maxLength":255},{"name":"properties","type":"object","required":false,"description":"Values for the event's properties. Conditions read them as trigger.<name>.","location":"body"}]
  responseMap: {"200":{"description":"Response for status 200","schema":{"success":true,"eventId":"evt_123456789","eventKey":"trigger.user.signed_up","contactId":"con_123456789","contactCreated":false,"enrollments":1,"properties":{"plan":"pro"}}},"400":{"description":"Response for status 400","schema":{"message":"Invalid event properties","why":"Missing required property \"plan\".","fix":"Fix property names/types and try again."}},"401":{"description":"Response for status 401","schema":{"message":"Authentication required"}},"404":{"description":"Response for status 404","schema":{"message":"Event not found","why":"No custom event \"trigger.user.signed_up\" exists for your organization.","fix":"Create the event first, or verify the key / ID."}}}
  codeSamples:
    - id: node
      lang: javascript
      label: Node.js
      source: |-
        import { Reloop } from "reloop-email";
        
        const reloop = new Reloop({ apiKey: "rl_123456789" });
        
        const { event, eventError } = await reloop.events.track({
          event: "user.signed_up",
          email: "john.doe@example.com",
          properties: { plan: "pro" },
        });
        if (eventError) throw eventError;
    - id: python
      lang: python
      label: Python
      source: |-
        import requests
        
        res = requests.post(
            "https://reloop.sh/api/workflow/v1/events/track",
            headers={"x-api-key": "rl_123456789"},
            json={
                "event": "user.signed_up",
                "email": "john.doe@example.com",
                "properties": {"plan": "pro"},
            },
        )
        res.raise_for_status()
    - id: php
      lang: php
      label: PHP
      source: |-
        <?php
        
        $ch = curl_init('https://reloop.sh/api/workflow/v1/events/track');
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'x-api-key: rl_123456789',
                'Content-Type: application/json',
            ],
            CURLOPT_POSTFIELDS => json_encode([
                'event' => 'user.signed_up',
                'email' => 'john.doe@example.com',
                'properties' => ['plan' => 'pro'],
            ]),
        ]);
        $response = curl_exec($ch);
    - id: go
      lang: go
      label: Go
      source: |-
        body := strings.NewReader(`{
          "event": "user.signed_up",
          "email": "john.doe@example.com",
          "properties": {"plan": "pro"}
        }`)
        
        req, _ := http.NewRequest("POST", "https://reloop.sh/api/workflow/v1/events/track", body)
        req.Header.Set("x-api-key", "rl_123456789")
        req.Header.Set("Content-Type", "application/json")
        
        res, err := http.DefaultClient.Do(req)
    - id: ruby
      lang: ruby
      label: Ruby
      source: |-
        require "net/http"
        require "json"
        
        uri = URI("https://reloop.sh/api/workflow/v1/events/track")
        res = Net::HTTP.post(
          uri,
          {
            event: "user.signed_up",
            email: "john.doe@example.com",
            properties: { plan: "pro" },
          }.to_json,
          "x-api-key" => "rl_123456789",
          "Content-Type" => "application/json",
        )
    - id: curl
      lang: bash
      label: cURL
      source: |-
        curl -X POST https://reloop.sh/api/workflow/v1/events/track \
          -H "x-api-key: rl_123456789" \
          -H "Content-Type: application/json" \
          -d '{"event": "user.signed_up","email": "john.doe@example.com","properties": {"plan": "pro"}}'
---
> For the complete documentation index, see [llms-docs.txt](/llms-docs.txt) or the site index [llms.txt](/llms.txt). Full docs corpus: [llms-full-docs.txt](/llms-full-docs.txt). Prefer markdown URLs (append `.md`) for agent consumption. Product skill: [skill.md](/skill.md).


{/* This file was generated by the OpenAPI doc generator. Do not edit this file directly. Run `bun run generate:api-docs` to regenerate. */}

<APIPage />
