---
slug: server-events-api
title: "How do I report conversions server-side?"
category: installation
locale: en
updated: 2026-10-17
keywords: ["Server Events API","server-side","backend","CRM","shop","REST"]
questions: ["How do I send events from my shop, CRM or backend?","Server-side tracking","Conversion API","Send events from the backend","How do I send an order or lead?","Which address do I send server events to?","What is the host of the Server Events API?","Does the event_id have to be unique across all websites?"]
url: https://bench.metrunio.com/en/help/server-events-api
---

# How do I report conversions server-side?

**How do I send events from my shop, CRM or backend?**

Through POST /v1/server/events to the collector, with the server key in the authorization header. The portal shows the address and the ready-made call for your website under “Setup” on the “Server Events API” tab. The call is independent of the browser and therefore robust against ad blockers and short-lived cookies.

| Method | Path | Purpose |
| --- | --- | --- |
| POST | /v1/server/events | events and conversions, signature optional |
| POST | /v1/webhooks/conversions | webhooks, signature required |

Authenticate with authorization: Bearer <SERVER_KEY> or the header x-metrunio-server-key. The server key has scope “server” and is bound to exactly one website. You create it in “Setup” on the “Server Events API” tab, where you also renew and revoke it.

You send to the collector, not to the product API. Its address appears on the same tab in the ready-made call for your website; the example below uses `$METRUNIO_COLLECTOR` in its place. If your own measurement domain is in operation, the tab shows it and the call goes there.

## Example

```bash
curl -X POST "$METRUNIO_COLLECTOR/v1/server/events" \
  -H "authorization: Bearer $METRUNIO_SERVER_KEY" \
  -H "content-type: application/json" \
  -d '{
    "site_id": "site_demo_shop",
    "events": [{
      "event_id": "order-12345",
      "event_type": "purchase",
      "occurred_at": "2026-08-12T10:15:00Z",
      "order_id": "12345",
      "value": "149.90",
      "currency": "EUR",
      "consent_state": "granted",
      "consent_purposes": ["analytics", "marketing"]
    }]
  }'
```

## Response

```json
{
  "received": 1,
  "accepted": 1,
  "duplicates": 0,
  "rejected": 0,
  "blocked": 0,
  "results": [{ "eventId": "order-12345", "status": "accepted" }]
}
```

Partial failures are possible: one invalid event does not discard the whole batch. The response states a status per event and, on failure, the reason.

The event_id makes a report safe to retry: if the same event_id arrives again from a server for the same website and environment, it does not count twice and the response says DUPLICATE_EVENT. So derive it from your system, for example `order-12345`. Two websites, test and production may use the same event_id, and an event_id from the browser never takes up one of your server’s.

## Linking to the journey

To connect the server-side conversion with website contacts, pass at least one shared identifier: anonymous_id, session_id, click_id or an already pseudonymised user_id. Without a shared identifier the conversion stays visibly “unattributed”; it is not guessed.

A funnel step of an application takes the same route: `event_type: "goal"` with `goal_key` and `user_id`, event ID such as `customer-4711-shop_created`. It counts once per customer; without a customer identifier it is rejected. An unknown key creates the definition in the portal automatically.

Report a subscription payment as a purchase with its own order number, plus `subscription_id` and `subscription_renewal: true`. It is attributed according to the first order of the same subscription and never counts as a new customer. The article on subscription renewals explains the details.

> **Caution:** Consent applies server-side too. Pass consent_state and consent_purposes. For journeys and ad attribution an event needs matching consent; without it the event is rejected. The exception is purchases and refunds without a decision (unknown): they are stored for revenue reconciliation, without browser, customer or advertising identifiers, and appear as not attributed. After a refusal (denied) this applies only with the additional instruction for revenue reconciliation. The details are in the article on consent for server events.

## Also asked

- Server-side tracking
- Conversion API
- Send events from the backend
- How do I send an order or lead?
- Which address do I send server events to?
- What is the host of the Server Events API?
- Does the event_id have to be unique across all websites?

## Related

- https://bench.metrunio.com/en/help/server-events-signatur
- https://bench.metrunio.com/en/help/webhooks-conversions
- https://bench.metrunio.com/en/help/conversion-nicht-zugeordnet
- https://bench.metrunio.com/en/help/funnel-schritte-einbauen
- https://bench.metrunio.com/en/help/eigene-messdomaene
- https://bench.metrunio.com/en/help/abo-folgezahlungen
