# Server-Side Hybrid API

### Postman Collection

The API documentation includes a [collection of requests with examples](https://www.postman.com/gravity-field/workspace/gravity-field-server-side-api/overview). It is designed for easy browsing, allowing you to explore the functionality even without a Postman account.

If you are already using Postman, you can fork and run the collection directly in your own account.

### Authorization

This API uses [basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#basic_authentication). For the authorization, you will need to use your section's API-key.

Your authorization header should look like this:

```
--header 'Authorization: Basic YWhhbWwsdG9uQGFwaWdlZS5jb206bClwYXNzdzByZAo'
```

You can request the API Key from “Settings” → “API Keys”

### Hybrid Implementation

The hybrid implementation combines elements from both frontend and server-side implementation. To ensure seamless user identification, you will need to pass the following Gravity Field values in the context of server-side API calls:

* Cookie with the user ID
* Cookie with the session ID

The values of these cookies are set differently depending on whether the user is new or returning.

For new users (interacting with the site for the first time), campaigns are requested with *user.slid* and *session.sl* set to *null*. In response to the "choose" request, values for cookies \_s*lid*, *\_slid\_server*, *\_slsession* will be returned, these should be used in subsequent requests for this user. Do not set HttpOnly parameter for the new cookies.

For returning users, in hybrid requests, you will need to pass:

* In the *user.slid* attribute:
  * The value of the cookie *\_slid* and/or *\_slid\_server* (if both cookies have values, pass both; in some cases, the user may have only one of these cookies). The values of cookies *\_slid* and *\_slid\_server* passed in the requests must match their values in the user's browser.
* In the *session.sl* attribute:
  * The value of the cookie *\_slsession* (if it exists). The value of the cookie *\_slsession* passed in the requests must match its value in the user's browser.

Current values of cookies *\_slid*, *\_slid\_server*, *\_slsession* are returned in every response to the `choose` request.

### Creating campaigns

Creating new API-campaigns requires the involvement of the development team, specifically for:

* Implementing a campaign request using `choose`.
* Processing the received response (JSON) and rendering the result.
* Passing information about a user interactions with the campaign using `engagement`.

To make requests, you need to use the API keys generated in your account (you can turn to the team working on your project to get the API keys).

### Page: Sending Page View Information

For personalization to work correctly, it is necessary to send information about page views on the website (or screen views in the application) for all the users. Typically, this task is solved together with the campaign request via a dedicated parameter in the choose request (see below). However, there is also the option to send page view information separately from the campaign request using /page endpoint.

{% hint style="info" %}
When using hybrid implementation, it is necessary to send page view information if there is no frontend secipt implemented on that page.
{% endhint %}

{% openapi src="<https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media>" path="/ssapi/page" method="post" %}
[SSAPI\_hybrid.yaml](https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media)
{% endopenapi %}

### Events: Transmitting Information About Events

In order to collect statistics and optimize campaigns, it is necessary to provide Gravity Field with information about user actions on the site (in the application).

List of possible events: [3.-events](https://developer.gravityfield.ai/lang/en/implementation/client-side-integration/3.-events "mention")

{% hint style="info" %}
It is recommended to exclude events generated by bots and the QA team from the transmitted data.
{% endhint %}

{% openapi src="<https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media>" path="/ssapi/event" method="post" %}
[SSAPI\_hybrid.yaml](https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media)
{% endopenapi %}

### Choose: Requesting Campaigns

Both Custom Code and Recommendations campaigns could be requested by `choose`.

The campaigns are identified in the requests by API Selector Name or API Selector Groups.

<figure><img src="https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-54c6d8123dbf6c843b58d03e2b97e3f358cdfc5d%2Fimage%20(1)%20(2).png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
In case of Hybrid implementation you can use a choose-request with`null`in `user.slid` and`session.sl` to get new identifiers.
{% endhint %}

{% openapi src="<https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media>" path="/ssapi/choose" method="post" %}
[SSAPI\_hybrid.yaml](https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media)
{% endopenapi %}

**To handle errors gracefully, you should:**

1. Set a response timeout.
2. In case of timeout or response different from status 200, you will need either:
   * display nothing
   * display a stub (default banner, pre-installed set of products in the widget, etc.). Additionally, we recommend to send a custom fallback event to Gravity Field

### Engagement: Passing Information About Users’ Interactions With Personalization Campaigns

In order to gather valuable statistics and further optimize your campaigns, you should pass the information about users's interactions with personalization campaigns.

{% openapi src="<https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media>" path="/ssapi/engagement" method="post" %}
[SSAPI\_hybrid.yaml](https://3786223776-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMtBULwktLmojWzNHUD1%2Fuploads%2Fgit-blob-b4a3efdd66a63d62b314c6a87fee2093115e1136%2FSSAPI_hybrid.yaml?alt=media)
{% endopenapi %}

### Rate limits <a href="#rate-limits" id="rate-limits"></a>

All requests are limited to 500 requests per second (RPS) per section.

### Additional Recommendations

* Keep API keys safe and do not disclose them to third parties
* Ensure that all API calls for the same user within one session have the same User and Session IDs
* Request recommendations asynchronously to speed up content rendering
* Set a timeout for waiting for a response from the API. Prepare a default content option in advance for displaying when there is no response. It is also recommended to keep statistics on timings and cases when a response from the API was not received (additional events can be sent in case of response timeouts).

### Debugging

You can view all your requests and corresponding responses in real-time in your Gravity Field account (Settings/API Logs).
