> ## Documentation Index
> Fetch the complete documentation index at: https://docs.suprsend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send and Track Events

> Learn how to send events to trigger workflows, with code snippets and examples.

## Pre-Requisites

[Create User Profile](/docs/go-create-user-profile)

## Send Event

You can send event to Suprsend platform by using the `supr_client.track_event` method. When you call `supr_client.track_event`, the SDK internally makes an `HTTP` call to SuprSend Platform to register this request, and you'll immediately receive a response indicating the acceptance status. The actual processing/execution of event happens asynchronously.

<CodeGroup>
  ```go Request theme={"system"}
  ev := &suprsend.Event{
    EventName:  "__event_name__",
    DistinctId: "_distinct_id_",
    Properties: map[string]interface{}{
      "k1": "v1",
    },
    IdempotencyKey: "_unique_request_id_"
  }

  // Send event to Suprsend by calling .TrackEvent
  _, err = suprClient.TrackEvent(ev)
  if err != nil {
    log.Fatalln(err)
  }
  ```

  ```go Sample Code theme={"system"}

  ev := &suprsend.Event{
    EventName:  "product_purchased", // Mandatory, name of the event you're tracking
    DistinctId: "0fxxx8f74-xxxx-41c5-8752-xxxcb6911fb08", // Mandatory, Unique id of user in your application
    Properties: map[string]interface{}{
      "first_name": "User",
      "spend_amount": "$10",
      "nested_key_example": map[string]interface{}{
        "nested_key1": "some_value_1",
        "nested_key2": map[string]interface{}{
          "nested_key3": "some_value_3",
        },
      },
      IdempotencyKey: "abcd-1234-abc6"
    }

    // Send event to Suprsend by calling .TrackEvent
    _, err = suprClient.TrackEvent(ev)
    if err != nil {
      log.Fatalln(err)
    }
  ```

  ```go Response theme={"system"}
  // Response structure
  {
      "success": True, // if true, request was accepted.
      "status": "success",
      "status_code": 202, // http status code
      "message": "OK",
  }

  {
      "success": False, // error will be present in message
      "status": "fail",
      "status_code": 500, // http status code
      "message": "error message",
  }
  ```
</CodeGroup>

| Parameter        | Description                                                                                                                                         | Type       | Obligation  |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ----------- |
| `DistinctId`     | `distinct_id` of user performing the event                                                                                                          | string     | *mandatory* |
| `EventName`      | string identifier for the event like `product_purchased`                                                                                            | string     | *mandatory* |
| `Properties`     | a dictionary representing event attributes like `first_name` Event properties can be used to pass template variables in case of event based trigger | Dictionary | *optional*  |
| `IdempotencyKey` | `idempotency_key` is the unique identifier for an event, and expires in 24 hours.                                                                   | string     | optional    |

<Warning>
  **Event naming guidelines:**

  Event Name or Property Name should not start with  or , as we have reserved these symbols for our internal events and property names.
</Warning>

### Idempotent requests

SuprSend supports idempotency to ensure that requests can be retried safely without duplicate processing. If Suprsend receives and processes a request with an idempotency\_key, it will skip processing requests with same `idempotency_key` for next 24 hours. You can use this key to track webhooks related to workflow notifications.

Idempotency key should be unique that you generate for each request. You may use any string up to 255 characters in length. Any space at start and end of the key will be trimmed.

Here are some common approaches for assigning idempotency keys:

* **Generate a random UUID** for each request.
* **Construct the idempotency key by combining relevant information about the request**. This can include parameters, identifiers, or specific contextual details that are meaningful within your application. for example, you could concatenate the user ID, action, and timestamp to form an idempotency key like `user147-new-comment-1687437670`
* **Request-specific Identifier**: If your request already contains a unique identifier, such as an order ID or a job ID, you can use that identifier directly as the idempotency key.

## Add file attachment in event (for email)

To add one or more Attachments to a Notification (viz. Email), you can just append the filepath of attachment to the event instance.

* Call `event.AddAttachment()` for each file with an accessible URL.
* Ensure that file\_path is a publicly accessible URL. Since event API size can't be > 100 KB, local file paths can't be passed in event attachment.

<CodeGroup>
  ```go Request theme={"system"}
  ev := &suprsend.Event{
    EventName:  "invoice_generated",
    DistinctId: "0fxxx8f74-xxxx-41c5-8752-xxxcb6911fb08",
    Properties: map[string]interface{}{...}
  }

  // Add attachment (If needed) by calling .AddAttachment
  err = ev.AddAttachment("https://www.adobe.com/sample_file.pdf")
  if err != nil {
    log.Println(err)
  }

  // Send event to Suprsend by calling .TrackEvent
  _, err = suprClient.TrackEvent(ev)
  if err != nil {
    log.Fatalln(err)
  }
  ```

  ```go Response theme={"system"}
  # Response structure
  {
      "success": true, // if true, request was accepted.
      "status": "success",
      "status_code": 202, // http status code
      "message": "OK",
  }

  {
      "success": false, // error will be present in message
      "status": "fail",
      "status_code": 500, // http status code
      "message": "error message",
  }
  ```
</CodeGroup>

<Warning>
  Please add public accessible URL only as attachment file otherwise it will throw an error `404 not found` and workflow will not be triggered
</Warning>

## Bulk API for multiple event requests

You can use Bulk API to send multiple events. Use .Append() on bulk\_events instance to add however-many-records to call in bulk.

<CodeGroup>
  ```go Request theme={"system"}
  ev1 := &suprsend.Event{
    EventName:  "__event_name1__",
    DistinctId: "__distinct_id1__",
    Properties: map[string]interface{}{
      "k1": "v1",
    }
  }

  ev2 := &suprsend.Event{
    EventName:  "__event_name2__",
    DistinctId: "__distinct_id2__"
  }

  // Create bulkEvents instance
  bulkIns := suprClient.BulkEvents.NewInstance()

  // Add all events to bulk Instance
  bulkIns.Append(ev1, ev2)

  // call trigger to send all these events to SuprSend
  bulkResponse, err := bulkIns.Trigger()
  if err != nil {
    log.Fatalln(err)
  }
  log.Println(bulkResponse)
  ```

  ```go With Email attachment theme={"system"}
  ev1 := &suprsend.Event{
    EventName:  "__event_name1__",
    DistinctId: "__distinct_id1__",
    Properties: map[string]interface{}{
      "k1": "v1",
    }
  }

  //Add Email Attachment to event 1
  err = ev.AddAttachment("https://file_path_1.pdf")
  if err != nil {
    log.Println(err)
  }

  ev2 := &suprsend.Event{
    EventName:  "__event_name2__",
    DistinctId: "__distinct_id2__"
  }

  //Add Email Attachment to event 2
  err = ev.AddAttachment("https://file_path_2.pdf")
  if err != nil {
    log.Println(err)
  }

  // Create bulkEvents instance
  bulkIns := suprClient.BulkEvents.NewInstance()

  // Add all events to bulk Instance
  bulkIns.Append(ev1, ev2)

  // call trigger to send all these events to SuprSend
  bulkResponse, err := bulkIns.Trigger()
  if err != nil {
    log.Fatalln(err)
  }
  log.Println(bulkResponse)
  ```

  ```go Response theme={"system"}
  suprsend.BulkResponse{
    Status : "success",
    Total : 10, // number of records sent in bulk
    Success : 10, // number of records succeeded
    Failure : 0, // number of records failed
    FailedRecords : [],
  }

  suprsend.BulkResponse{
    Status : "fail",
    Total : 10, // number of records sent in bulk
    Success : 0, // number of records succeeded
    Failure : 10, // number of records failed
    FailedRecords : [{"record": {...}, "error": "error_str", "code": 500}]
  }

  suprsend.BulkResponse{
    Status : "partial",
    Total : 10, // number of records sent in bulk
    Success : 6, // number of records succeeded
    Failure : 4, // number of records failed
    FailedRecords : [{"record": {...}, "error": "error_str", "code": 500}]
  }
  ```
</CodeGroup>

***
