# HTTP API

You can use the Freshpaint HTTP API to send server side events into Freshpaint. See the [server side source docs](https://documentation.freshpaint.io/integrations/sources/server-side) for information on how you can use server side events.

## Using the HTTP API

The Freshpaint server-side API can be used to send data from your backend to Freshpaint. To send a server-side event, you make a `POST` request to <https://api.perfalytics.com/track> with the event you want to send. Events have the following format:

```
{
    "event": "<name of the event>",
    "properties": {
        "distinct_id": "<unique user identifier>",
        "token": "<your environment id>",
        "time": <the epoch time when the event occurred, in seconds>,
        <additional properties>
    }
}
```

#### Properties

The following properties are **required**:

| Argument         | Type     | Description                                                                                                                                                                                                                                                      |
| ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **distinct\_id** | `String` | An identifier that uniquely identifies the user that performed the event (usually email address). This is the same as the identifier you would pass to [freshpaint.identify()](https://documentation.freshpaint.io/developer/freshpaint-sdk-reference#identify). |
| **token**        | `String` | Your environment ID. You can get it from the Server Side API section on the [sources page](https://app.freshpaint.io/sources) of the Freshpaint app.                                                                                                             |
| **time**         | `Number` | The epoch time the event occurred, in seconds. The epoch time is the number of seconds since January 1st 1970.                                                                                                                                                   |

The following properties are **optional**:

| **$device\_id** | `String` | A unique identifier for the device the event was sent from. This is sometimes referred to as the `anonymous_id`.                                                                              |
| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **$insert\_id** | `String` | A unique identifier for this event. Events that have the same `$insert_id` will be treated as duplicates by certain destinations that de-duplicate events by the `$insert_id` value received. |

In addition to the above properties, you can send any additional custom properties you want.

### IP Address

The IP address from where you send the server-side event will be automatically captured. It may, however, be the case that you want to submit a different IP address. For example, your server may be located in a data center, but you may want a purchase event to reflect the IP address of the actual purchaser.

In that case, you can send the IP address by submitting a property named `$ip`. For example:

```
{
  "event": "Purchase",
  "properties": {
    "distinct_id": "123",
    "$ip": "1.2.3.4",
    "price": 500
  }
}
```

### **Example code:**

{% tabs %}
{% tab title="Curl" %}

```bash
curl -X POST -H "Content-Type: application/json" -d '{
    "event": "Purchase",
    "properties": {
        "distinct_id": "13793",
        "token": "2ce2b45b-af44-4426-a3ef-a314abce9c85",
        "time": 1577836800,
        "price": 500
    }
  }' https://api.perfalytics.com/track
```

{% endtab %}

{% tab title="JavaScript" %}
If you can't use our [JavaScript SDK](https://documentation.freshpaint.io/reference/developer/freshpaint-sdk-reference), you can send a raw HTTP request as well:

```javascript
const payload = {
  event: "Purchase",
  properties: {
    distinct_id: "13793",
    token: "2ce2b45b-af44-4426-a3ef-a314abce9c85",
    time: 1577836800,
    price: 500,
  },
};

fetch("https://api.perfalytics.com/track", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
});
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

payload = {
    "event": "purchase",
    "properties": {
        "distinct_id": "13793",
        "token": "2ce2b45b-af44-4426-a3ef-a314abce9c85",
        "time": 1577836800,
        "price": 500,
    },
}

requests.post("https://api.perfalytics.com/track", json=payload)
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'json'
require 'net/http'

uri = URI('https://api.perfalytics.com/track')
payload = {
    "event" => "purchase",
    "properties" => {
        "distinct_id" => "13793",
        "token" => "2ce2b45b-af44-4426-a3ef-a314abce9c85",
        "time" => 1577836800,
        "price" => 500,
    },
}

Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
  req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
  req.body = payload.to_json
  puts http.request(req)
end
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
The Freshpaint HTTP API will return a 200 as soon as the event has been received. Validation of the event will be performed after the event is received. If you want to confirm Freshpaint has received your event, you should check the Freshpaint Live View.
{% endhint %}

{% hint style="info" %}
Freshpaint APIs are fast, and we're committed to 99.9% uptime (see our SLA <https://www.freshpaint.io/sla>). That said, we recommend communicating with Freshpaint APIs in a "fire and forget" manner, for example by making the request from a separate thread or by using an async-await pattern if your language supports it. We recommend this so that your server processing is not blocked waiting for the Freshpaint API to respond.
{% endhint %}

## Server-side Identify

You can also pass identify events server-side to attach user properties to users from the server. To do so, you pass a server-side event to the HTTP API with the following format:

```
{
  "event": "$identify",
  "properties": {
    "distinct_id": "<user identifier>",
    "token": "<your freshpaint environment id>",
    "time": <epoch time in seconds>,
    "$device_id": <anonymous user id (optional)>,
    "$user_props": {
      <any properties you want to attach to the user>
    }
  }
}
```

The following properties are **required**:

| Argument         | Type     | Description                                                                                                                                          |
| ---------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **distinct\_id** | `String` | An identifier that uniquely identifies the user that performed the event (usually email address).                                                    |
| **token**        | `String` | Your environment ID. You can get it from the Server Side API section on the [sources page](https://app.freshpaint.io/sources) of the Freshpaint app. |
| **time**         | `Number` | The epoch time the event occurred. The epoch time is the number of seconds since January 1st 1970.                                                   |

## Configuring Which Destinations Server-Side Events Are Sent To

There are two ways to configure server-side events to go to. First you can pass in a list of hardcoded destinations as part of the event in the `$options` property. You can either pass in a list of destinations the event should not go to:

```
{
  "event": "Test Event",
  "properties": {
    "distinct_id": "test-user-id",
    "token": "6dc2e9e2-3b9c-4259-b004-21f39dd6c81a",
    "time": 1577836800,
    "a": 5, 
    "$options": {"integrations": {"Mixpanel": false}}
  }
}
```

Or pass in a list of destinations the event should only go to:

```
{
  "event": "Test Event",
  "properties": {
    "distinct_id": "test-user-id",
    "token": "6dc2e9e2-3b9c-4259-b004-21f39dd6c81a",
    "time": 1577836800,
    "a": 5, 
    "$options": {"integrations": {"All": false, "Mixpanel": true}}
  }
}
```

Alternatively, you can go to the event schema page for the event, go to `Settings`. And flip the toggle for "Override hardcoded destinations". Then you'll be able to toggle each event on a per destination basis.

## De-duplication

Events sent to the HTTP API are considered duplicates if they have the same value for the `$insert_id` property. If `$insert_id` is not provided, Freshpaint will compute a value based on the `time` and `$device_id` properties, so that if two events have the same value for these properties then they will be treated as duplicates.

To avoid events being de-duplicated erroneously, you may want to ensure that the `time` property you provide to the HTTP API uses millisecond precision.

For ultimate control over de-duplication behavior, consider providing an `$insert_id` with each event. A good way to generate an `$insert_id` is to hash together several pieces of information that uniquely identify the event, such as the timestamp, device id, user id, and event name.

## Rate Limits

There is a 5000 request/second burst request limit for the HTTP API. Please throttle your requests accordingly. Contact <support@freshpaint.io> if you have any questions.
