# Synchronization Methods

## Introduction

Event synchronization allows menta tech to understand your inventory to enable resale. There are different methods to achieve this synchronization, depending on your platform's technical capabilities.

Regardless of the chosen method, the information structure (how you define tickets and prices) is critical. Consult the **[Data Structure](/en/guides/infoStructure)** guide to understand how to model your inventory correctly.

## Integration Options

{% table highlight-first=true highlight-row=2 %}
| Option | Description | When it makes sense | Benefits | Limitations |
|--------|-------------|----------------------|------------|--------------|
| Using the menta tech API (recommended) | The platform sends CREATE/UPDATE requests directly to menta | When real-time sync and accuracy matter | Near real-time updates, no polling, most scalable option | Requires emitting outbound updates from the backend |
| Event endpoint exposed by the platform | menta tech periodically queries an event endpoint from the ticketing platform | When an event endpoint already exists or a pull model is preferred | Easy adoption; the platform controls structure and frequency | Data can become stale; polling adds load and isn’t ideal for frequent changes |
| Manual event upload | Events are created manually, without APIs | For pilots or low-volume partners | No development, fastest time to production | Not scalable; manual operations; higher risk of stale data |
{% /table %}

{% conditionaltabs id="tabs-1765309889524" %}

{% tab label="menta tech API" %}
## Sending via API (Push)

This is the recommended method for robust integrations. Your backend acts as the source of truth and notifies menta whenever there are changes.

### Implementation

You must send requests to our API whenever an event is created, updated, or canceled.

```bash
POST /v1/events
```

The request body (JSON) will depend on the data model you choose (Standard, Simple Price, or Advanced). **Review the [Data Structure](/en/guides/infoStructure)** guide to see the required JSON schemas.

Useful links:
- <a href='https://connect.mentatech.io/es/api/post-events' target="_blank">Create event (API Reference)</a>
- <a href='https://connect.mentatech.io/es/api/put-events' target="_blank">Update event (API Reference)</a>
{% /tab %}

{% tab label="Endpoint exposed by your platform" %}
## Pull Endpoint

Your platform exposes a public URL (e.g., `https://api.yourplatform.com/menta-feed`) and menta queries it periodically to fetch updates.

### Endpoint Requirements

The endpoint must return a JSON with the list of active events (an array of objects). The structure of each event must include location details, producers, and shows.

Within each show, the `ticketOptions` structure must follow the definitions in the **[Data Structure](/en/guides/infoStructure)** guide.

### Required JSON structure

Below is an example of how the event array returned by your endpoint should look:

{% columns gap="2rem" align="start" %}

{% column width="1" valign="top" %}
**Key fields:**
- **Root Array**: The response must be a list `[...]`.
- **Event**: `title`, `description`, `externalReferenceId`.
- **Location**: `city`, `venueName`, `address`.
- **Producers**: Contact information.
- **Shows**: Array of performances.
  - **status**: Show status (`ON_SALE`, `CANCELLED`, `RESCHEDULED`, `ANNOUNCED`, `HIDDEN`, `PRIVATE`).
  - **dates**: Lifecycle dates object (`startsAt`, `salesStartAt`, `salesEndAt`, `publicAt`).
  - **tags**: Array of strings in `key:value` format.
  - **ticketOptions**: Critical array for resale (access categories). Each item includes `price` (category price **excluding commissions and fees**) and, optionally, `area` (zone grouping — multiple ticketOptions can share the same `area`).
  - **priceTypes** *(optional)*: Price types available for sale (e.g., Adult, Special Discount, Early Bird).
  - **combinations** *(required if `priceTypes` is present)*: Valid `ticketOption` + `priceType` combinations that actually exist in your catalog. Each combination carries its own `price` (also excluding commissions and fees) and, optionally, a `description`.
{% /column %}

{% column width="1" valign="top" %}
```json
[
  {
    "title": "Example Concert",
    "description": "Example event description.",
    "externalReferenceId": "evt_example_001",
    "shows": [
        {
            "title": "Example Concert - Main Show",
            "primarySalesUrl": "https://yourplatform.com/event/example-concert/show/001",
            "images": [
                {
                    "url": "https://example.com/images/main-event.jpg",
                    "kind": "main"
                }
            ],
            "showId": "show_example_001",
            "status": "ON_SALE",
            "dates": {
                "startsAt": "2025-12-15T20:00:00.000-03:00",
                "salesStartAt": "2025-10-01T10:00:00.000-03:00",
                "salesEndAt": "2025-12-15T18:00:00.000-03:00",
                "publicAt": "2025-09-15T00:00:00.000-03:00"
            },
            "tags": ["genre:rock", "tour:2025"],
            "ticketOptions": [
                {
                    "title": "General",
                    "ticketId": "GEN_001",
                    "description": "General admission to the event",
                    "currency": "USD",
                    "price": 100,
                    "area": "Field"
                },
                {
                    "title": "VIP",
                    "ticketId": "VIP_001",
                    "description": "VIP access with exclusive benefits",
                    "currency": "USD",
                    "price": 250,
                    "area": "Grandstand"
                }
            ],
            "priceTypes": [
                {
                    "priceTypeId": "adult",
                    "title": "Adult"
                },
                {
                    "priceTypeId": "special-discount",
                    "title": "Special Discount"
                }
            ],
            "combinations": [
                {
                    "ticketOptionId": "GEN_001",
                    "priceTypeId": "adult",
                    "price": 100,
                    "description": "General – Adult"
                },
                {
                    "ticketOptionId": "GEN_001",
                    "priceTypeId": "special-discount",
                    "price": 70
                },
                {
                    "ticketOptionId": "VIP_001",
                    "priceTypeId": "adult",
                    "price": 250
                }
            ]
        }
    ],
    "location": {
        "city": "Buenos Aires",
        "state": "Buenos Aires",
        "venueName": "Example Stadium",
        "address": "Example Ave 1234",
        "country": "Argentina"
    },
    "producers": [
        {
            "name": "Example Producer",
            "emails": [
                "contact@example-producer.com"
            ],
            "producerId": "prod_001"
        }
    ]
  }
]
```
{% /column %}
{% /columns %}

{% callout type="warning" title="priceTypes and combinations" %}
`priceTypes` is **optional**: if your catalog does not have price variations within the same access category, you can omit this array and work only with `ticketOptions` (Standard model).

However, **if you send `priceTypes`, you must send `combinations`**. menta tech does not generate combinations automatically: only the combinations you explicitly declare in that array will exist. If a `ticketOption` + `priceType` combination does not appear in `combinations`, it will not exist in menta even though both dimensions are declared.

Review the **[Data Structure](/en/guides/infoStructure)** guide to understand when each model makes sense.
{% /callout %}

{% callout type="info" title="Prices without commissions or fees" %}
Both `ticketOption.price` and `combination.price` must be expressed **excluding commissions and fees**: it's the base price of the category (or the combination) as you actually charge it, without service fees or additional taxes you may add at primary checkout.

When `combinations` are present, the combination price **takes precedence** over the `price` declared on the associated ticketOption; the ticketOption becomes a reference for the category.
{% /callout %}

{% callout type="info" title="Grouping ticketOptions with area" %}
The `area` field on `ticketOption` is **optional** and exists to **group categories located in a similar zone** of the venue. Multiple ticketOptions can share the same `area` value.

For example, if "Upper Grandstand" contains three commercial categories (`Upper Grandstand VIP`, `Upper Grandstand Regular`, `Upper Grandstand Accessible`), all three can declare `"area": "Upper Grandstand"`. menta uses this grouping for filters, navigation, and zone-level metrics.
{% /callout %}
{% /tab %}

{% tab label="Manual event upload" %}
## Manual upload

For low volumes or pilot tests, it is possible to upload events via files (CSV/Excel) processed by menta's operations team.

This method requires no development but has significant operational limitations and risk of data staleness. Contact your account manager if you wish to use this option.
{% /tab %}
{% /conditionaltabs %}

---

## Show Status

Each show includes a `status` field that represents its current lifecycle state. This status determines how the show is displayed and whether resale activity is allowed.

{% table highlight-first=true %}
| Status | Description | Visible to public | Resale enabled |
| :--- | :--- | :--- | :--- |
| `ON_SALE` | Tickets are actively being sold in the primary market. The show is publicly visible and resale is fully operational. | Yes | Yes |
| `ANNOUNCED` | The show has been publicly announced and is visible, but primary ticket sales have not started yet or have been paused. Users can see the event but cannot purchase tickets in the primary market. Resale may still be active if tickets were previously distributed. | Yes | Depends on configuration |
| `CANCELLED` | The show has been cancelled. No further sales or resale activity is allowed. Existing resale listings are removed and pending transactions are handled according to the cancellation policy. | Yes (marked as cancelled) | No |
| `RESCHEDULED` | The show has been moved to a new date or time. The `dates.startsAt` field reflects the updated schedule. Resale activity may continue under the new date depending on configuration. | Yes (marked as rescheduled) | Depends on configuration |
| `HIDDEN` | The show is not visible to the public. It does not appear in search results, event listings, or the resale marketplace. Typically used for shows that are being set up or temporarily removed. | No | No |
| `PRIVATE` | The show is restricted to a specific audience (e.g., invite-only, presale groups, or internal events). It is not visible in public listings but may be accessible via direct link or access code. | Only with direct access | Depends on configuration |
{% /table %}

{% callout type="info" title="Status and dates" %}
The `status` field reflects the **current operational state** of the show, while the `dates` object provides the **scheduled timeline**. For example, a show can have `status: "ANNOUNCED"` with a future `dates.salesStartAt` — meaning it will automatically transition to on-sale at that date. Always send both fields so menta tech can manage the show lifecycle accurately.
{% /callout %}

## Show Dates

The `dates` object groups all relevant dates for a show's lifecycle. All dates must be in ISO 8601 format.

{% table highlight-first=true %}
| Field | Description |
| :--- | :--- |
| `dates.startsAt` | Date and time when the show begins (the performance start time). This is the main reference date for the event. |
| `dates.salesStartAt` | Date and time when primary ticket sales open. Before this date, tickets cannot be purchased in the primary market. |
| `dates.salesEndAt` | Date and time when primary ticket sales close. After this date, tickets are no longer available in the primary market. |
| `dates.publicAt` | Date and time when the show becomes publicly visible on the web. Before this date, the show may exist internally but is not displayed to end users. |
{% /table %}

---

## Event Cancellation

{% callout type="warning" title="Critical importance" %}
**It is essential to notify menta tech when an event is cancelled.** Payment distribution to resale ticket sellers occurs a few days after the original event date. If an event is cancelled and menta is not notified, payments will be processed normally after the scheduled date and **there will be no way to recover the money** once distributed.
{% /callout %}

### Why is this so important?

When an event is cancelled:
1. **Resale buyers must be refunded** - menta automatically handles refunds if the cancellation is notified in time.
2. **Payments to sellers are stopped** - if the cancellation is not reported, sellers will receive payment as if the event had taken place.
3. **No post-distribution recovery** - once funds are distributed, transactions cannot be reversed.

### How to notify a cancellation

{% conditionaltabs id="tabs-cancellation" %}

{% tab label="menta tech API" %}
### Cancellation via API (Recommended)

To cancel an event through the API, use the cancellation endpoint:

```bash
POST /v1/events/:externalReferenceId/cancellation
```

Where `:externalReferenceId` is the unique identifier of the event in your ticketing system.

**Optional parameters:**
- `showId`: If you only want to cancel a specific show within the event, include this parameter in the query string.

{% apiembed endpoint="post-post-events-id-cancellation" show="link" width="auto" /%}

{% /tab %}

{% tab label="Endpoint exposed by your platform" %}
### Cancellation with Pull integration

If your integration is through an endpoint that menta queries periodically, you have two options:

**Option 1: Cancelled events feed**
Expose an additional endpoint (e.g., `https://api.yourplatform.com/menta-feed/cancelled`) that returns the list of cancelled events. menta will query this feed periodically.

```json
[
  {
    "externalReferenceId": "evt_example_001",
    "cancelledAt": "2025-01-15T10:30:00.000Z",
    "showId": "show_001" // optional, if only one show
  }
]
```

**Option 2: Direct API Call (Recommended)**
Even if your main integration is through pull, **we recommend using the cancellation API call** for real-time notifications:

```bash
POST /v1/events/:externalReferenceId/cancellation
```

This ensures the cancellation is processed immediately without waiting for the next polling cycle.
{% /tab %}

{% tab label="Manual event upload" %}
### Cancellation with manual upload

For manual upload integrations, you have two options:

**Option 1: API Call (Recommended)**
Even if event uploads are manual, we recommend implementing the cancellation API call:

```bash
POST /v1/events/:externalReferenceId/cancellation
```

**Option 2: Notification to Account Manager**
Since this type of integration is oriented towards lower-volume platforms, it is also possible to inform the cancellation directly to your account manager. However, this may cause delays in processing.

{% callout type="info" %}
Contact your account manager as soon as possible when an event is cancelled to avoid incorrect payments.
{% /callout %}
{% /tab %}

{% /conditionaltabs %}
