# Add an activity to a contact

**Activities** power the contact timeline, trigger workflows, and feed into RFM (recency, frequency, monetary) scoring.&#x20;

All activities have a `spend` that is automatically applied to the contacts lifetime value or LTV.

***

#### Creating an activity

`POST /activities`

At minimum, provide the contact ID, activity type, source, and when it happened:

{% code title="" overflow="wrap" lineNumbers="true" %}

```json
{
  "contact": 1042,
  "type": "Purchase",
  "source": "website",
  "happenedAt": "2026-04-07T14:30:00+00:00",
  "spend": 4500,
  "currencyCode": "GBP"
}
```

{% endcode %}

The `spend` field is in the smallest currency unit — 4500 means £45.00 for GBP, or $45.00 for USD.

#### Activity types

The `type` field must be one of these values:

<table><thead><tr><th>Type</th><th>When to use</th><th width="250">Additional fields</th></tr></thead><tbody><tr><td><code>Booking</code></td><td>Hotel or venue reservation</td><td>Include a <code>booking</code> object (see below)</td></tr><tr><td><code>Checked in</code></td><td>Guest arrives at venue</td><td>—</td></tr><tr><td><code>Checked out</code></td><td>Guest departs venue</td><td>—</td></tr><tr><td><code>Purchase</code></td><td>Non-Glu purchase or transaction</td><td><code>spend</code>, <code>currencyCode</code></td></tr><tr><td><code>Shopify order</code></td><td>Order from Shopify</td><td>Typically created automatically</td></tr><tr><td><code>Gift card registered</code></td><td>Gift card added to a contact</td><td><code>giftCard</code> Id </td></tr><tr><td><code>Login</code></td><td>Member logged in</td><td>—</td></tr><tr><td><code>Connected to wifi</code></td><td>Guest connected to venue wifi</td><td>—</td></tr><tr><td><code>Membership started</code></td><td>Contact started a membership</td><td>—</td></tr><tr><td><code>Changed tier</code></td><td>Contact moved to a different tier</td><td>—</td></tr><tr><td><code>Membership cancelled</code></td><td>Contact cancelled membership</td><td>—</td></tr><tr><td><code>Referral invite created</code></td><td>Contact sent a referral</td><td><code>referralInvite</code> (IRI reference)</td></tr><tr><td><code>Referral invite completed</code></td><td>Referral was completed</td><td><code>referralInvite</code> (IRI reference)</td></tr><tr><td><code>Golf reservation</code></td><td></td><td></td></tr><tr><td><code>Table reservation</code></td><td></td><td></td></tr></tbody></table>

#### Recording a purchase

For purchases made outside of Glu (in-store POS, external e-commerce, etc.):

```json
{
  "contact": 1042,
  "type": "Purchase",
  "source": "YourPOS",
  "happenedAt": "2026-04-07T19:45:00+00:00",
  "spend": 12750,
  "currencyCode": "GBP",
  "externalReference": "TXN-98765"
}
```

The `externalReference` field is important for deduplication — if you send the same activity type with the same external reference twice, Glu will recognise it as a duplicate rather than creating two entries.

#### Deduplication

Glu deduplicates activities using two methods:

1. **By `externalReference`**: If an activity of the same type already exists with the same external reference within the organisation, the existing activity is returned instead of creating a duplicate.
2. **By `giftCard`**: For gift card related activities, if an activity already exists for the same gift card, it won't be duplicated.

Always include an `externalReference` when syncing activities from external systems to make your integration idempotent.

#### Retrieving a single activity

<mark style="color:green;">`GET`</mark>` ``/activities/{id}`

{% code title="Response" lineNumbers="true" expandable="true" %}

```json
{
  "id": 5678,
  "contact": 1042,
  "happenedAt": "2026-04-07T14:30:00+00:00",
  "createdAt": "2026-04-07T14:30:05+00:00",
  "updatedAt": "2026-04-07T14:30:05+00:00",
  "type": "Purchase",
  "source": "website",
  "externalReference": "TXN-98765",
  "spend": 4500,
  "currencyCode": "GBP"
}
```

{% endcode %}

### Custom fields

### Common integration patterns

#### Syncing purchases from your POS

Record every in-store transaction to build a complete picture of customer spending:

```
Your POS                         Your Server                     Glu API
  │                                  │                              │
  │── Sale completed ───────────────►│                              │
  │                                  │── POST /contacts ───────────►│
  │                                  │◄── Contact (id: 1042) ──────│
  │                                  │                              │
  │                                  │── POST /activities ─────────►│
  │                                  │   {                          │
  │                                  │     contact: 1042,           │
  │                                  │     type: "Purchase",        │
  │                                  │     spend: 4500,             │
  │                                  │     externalReference: "..." │
  │                                  │   }                          │
  │                                  │◄── Activity created ────────│
```

The contact's `totalSpend`, `lastInteractedAt`, and RFM scores update automatically.

#### Enriching contacts from your CRM

Sync custom attributes from an external CRM or data source:

```bash
# 1. Find the contact
curl -s -H "x-api-key: $GLU_API_KEY" \
  "https://api.glu.io/contacts?emailAddress[]=jane@example.com"

# 2. Set custom field values
curl -X POST -H "x-api-key: $GLU_API_KEY" \
  -H "Content-Type: application/json" \
  "https://api.glu.io/contacts/1042/custom-fields" \
  -d '{"fieldName": "external_crm_id", "value": "CRM-48291"}'

curl -X POST -H "x-api-key: $GLU_API_KEY" \
  -H "Content-Type: application/json" \
  "https://api.glu.io/contacts/1042/custom-fields" \
  -d '{"fieldName": "preferred_language", "value": "French"}'
```

#### Hotel PMS integration

Record bookings and check-in/check-out events from your property management system:

```bash
# 1. Record the booking
curl -X POST -H "x-api-key: $GLU_API_KEY" \
  -H "Content-Type: application/json" \
  "https://api.glu.io/activities" \
  -d '{
    "contact": 1042,
    "type": "Booking",
    "source": "mews",
    "happenedAt": "2026-04-07T10:00:00+00:00",
    "externalReference": "RES-2026-1234",
    "booking": {
      "checkIn": "2026-06-15T15:00:00+00:00",
      "checkOut": "2026-06-18T11:00:00+00:00",
      "numberOfGuests": 2,
      "roomType": "Suite",
      "total": 75000,
      "currencyCode": "GBP",
      "customerReference": "SMITH-0607",
      "purpose": "Leisure",
      "origin": "Direct"
    }
  }'

# 2. Record the check-in when it happens
curl -X POST -H "x-api-key: $GLU_API_KEY" \
  -H "Content-Type: application/json" \
  "https://api.glu.io/activities" \
  -d '{
    "contact": 1042,
    "type": "Checked in",
    "source": "mews",
    "happenedAt": "2026-06-15T15:22:00+00:00",
    "externalReference": "RES-2026-1234-CHECKIN"
  }'
```

#### Activities and workflows

Activities can trigger workflows. For example, a workflow with a `booking_created` trigger will automatically run when a Booking activity is created. This lets you build automations like:

* Send a welcome email when a booking is recorded
* Award loyalty points when a purchase activity is logged
* Upgrade a membership tier when spend thresholds are met

You don't need to do anything extra — just create the activity and any matching active workflows will execute.

### Tips

* **Always include `externalReference`** when syncing from external systems to prevent duplicates on retry.
* **Use `source`** to identify where the activity came from — this helps when debugging and when building workflow conditions.
* **Amounts are always in lowest denomination** — pence for GBP, cents for USD/EUR.
* **Custom field names are case-sensitive** — use the exact `fieldName` from the custom field definition.
* **Custom field values are validated** — the API will return a 422 error if the value doesn't match the field type or isn't in the allowed options for a Select field.
* **Contact lookup by email** — if you don't have the contact ID, use `GET /contacts?emailAddress[]=email@example.com` to find it first, or use `POST /contacts` which will create or update by email and return the contact with its ID.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://glu.gitbook.io/docs/use-cases/add-an-activity-to-a-contact.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
