> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gleap.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API Samples

This page demonstrates the most common API workflow: creating or finding a session, creating a ticket, and adding a comment to that ticket.

## Base URL

The API host depends on the [data region](/documentation/guides/data-regions) of your project:

| Data region  | API host                  |
| ------------ | ------------------------- |
| EU (default) | `https://api.gleap.io`    |
| US           | `https://api.us.gleap.ai` |

<Info>
  The examples on this page use the EU host. If your project lives in another region, replace `https://api.gleap.io` with your region's host. API tokens are per project and only valid in the project's region.
</Info>

## Common Flow Example

This example walks through a complete workflow that you'll use frequently when integrating with the Gleap API.

### Step 1: Create or Find a Session

First, create a session to represent a user or contact. If a session with the same `userId` already exists, you can use that session ID instead.

**Endpoint:** `POST /v3/sessions`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_12345",
    "email": "john.doe@example.com",
    "name": "John Doe",
    "customData": {
      "plan": "premium",
      "signupDate": "2024-01-15"
    }
  }'
```

**Response:**

```json theme={null}
{
  "_id": "507f1f77bcf86cd799439011",
  "id": "507f1f77bcf86cd799439011",
  "userId": "user_12345",
  "email": "john.doe@example.com",
  "name": "John Doe",
  "customData": {
    "plan": "premium",
    "signupDate": "2024-01-15"
  },
  "createdAt": "2024-01-20T10:30:00.000Z",
  "lastActivity": "2024-01-20T10:30:00.000Z"
}
```

<Info>
  Save the `_id` or `id` from the response - you'll need it to create a ticket linked to this session.
</Info>

### Step 2: Create a Ticket

Now create a ticket and link it to the session you just created. The ticket represents a support request, bug report, or feature request.

**Endpoint:** `POST /v3/tickets`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/tickets \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Login button not working on mobile app",
    "type": "BUG",
    "session": "507f1f77bcf86cd799439011",
    "formData": {
      "description": "Users are unable to log in when clicking the login button on iOS devices. The button appears to be unresponsive."
    }
  }'
```

**Response:**

```json theme={null}
{
  "_id": "507f1f77bcf86cd799439022",
  "id": "507f1f77bcf86cd799439022",
  "title": "Login button not working on mobile app",
  "type": "BUG",
  "session": {
    "_id": "507f1f77bcf86cd799439011",
    "email": "john.doe@example.com",
    "name": "John Doe"
  },
  "formData": {
    "description": "Users are unable to log in when clicking the login button on iOS devices. The button appears to be unresponsive."
  },
  "createdAt": "2024-01-20T10:35:00.000Z",
  "updatedAt": "2024-01-20T10:35:00.000Z"
}
```

<Info>
  Save the `_id` or `id` from the ticket response - you'll need it to add comments to this ticket.
</Info>

### Step 3: Create a Comment

Add a comment to the ticket. Comments can be simple text or rich formatted content. You can also attach files.

**Endpoint:** `POST /v3/messages`

**Request (Simple Text Comment):**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "ticket": "507f1f77bcf86cd799439022",
    "comment": "Thank you for reporting this issue. We are looking into it and will update you soon."
  }'
```

**Request (Rich Formatted Comment with Attachments):**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "ticket": "507f1f77bcf86cd799439022",
    "comment": {
      "type": "doc",
      "content": [
        {
          "type": "paragraph",
          "content": [
            {
              "type": "text",
              "text": "We have identified the issue and deployed a fix. "
            },
            {
              "type": "text",
              "marks": [
                {
                  "type": "bold"
                }
              ],
              "text": "Please update to version 2.3.2"
            },
            {
              "type": "text",
              "text": " to resolve this problem."
            }
          ]
        },
        {
          "type": "paragraph",
          "content": [
            {
              "type": "text",
              "text": "If you continue to experience issues, please let us know."
            }
          ]
        }
      ]
    },
    "attachments": [
      {
        "name": "fix-screenshot.png",
        "url": "https://example.com/screenshots/fix-screenshot.png",
        "type": "image/png"
      }
    ]
  }'
```

**Request (Internal Note):**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "ticket": "507f1f77bcf86cd799439022",
    "comment": "This is a high-priority issue affecting multiple users. Escalating to the mobile team.",
    "isNote": true
  }'
```

**Response:**

```json theme={null}
{
  "_id": "507f1f77bcf86cd799439033",
  "id": "507f1f77bcf86cd799439033",
  "ticket": "507f1f77bcf86cd799439022",
  "comment": {
    "type": "doc",
    "content": [
      {
        "type": "paragraph",
        "content": [
          {
            "type": "text",
            "text": "We have identified the issue and deployed a fix. "
          },
          {
            "type": "text",
            "marks": [
              {
                "type": "bold"
              }
            ],
            "text": "Please update to version 2.3.2"
          },
          {
            "type": "text",
            "text": " to resolve this problem."
          }
        ]
      }
    ]
  },
  "type": "TEXT",
  "attachments": [
    {
      "name": "fix-screenshot.png",
      "url": "https://example.com/screenshots/fix-screenshot.png",
      "type": "image/png"
    }
  ],
  "user": {
    "_id": "507f1f77bcf86cd799439044",
    "email": "support@example.com",
    "firstName": "Jane",
    "lastName": "Support"
  },
  "createdAt": "2024-01-20T11:00:00.000Z",
  "updatedAt": "2024-01-20T11:00:00.000Z"
}
```

### Step 4: Create a Comment from Markdown

Instead of building the rich-text JSON structure yourself, you can send Markdown via the `markdownComment` field. The server converts it to rich text automatically, and it takes precedence over `comment` if both are set.

**Endpoint:** `POST /v3/messages`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "ticket": "507f1f77bcf86cd799439022",
    "markdownComment": "We have identified the issue and deployed a fix. **Please update to version 2.3.2** to resolve this problem."
  }'
```

<Info>
  Messages created through this endpoint are always attributed to the user that owns the API key. It is not possible to create a comment on behalf of a customer (session) via this endpoint.
</Info>

## Reading a Ticket's Status History

Every internal change to a ticket (status, assignee, team, priority, type, tags, title, due date) is recorded as a history entry. Use the ticket history endpoint to read them:

**Endpoint:** `GET /v3/tickets/{ticketId}/history`

**Request:**

```bash theme={null}
curl -X GET "https://api.gleap.io/v3/tickets/507f1f77bcf86cd799439022/history" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID"
```

**Response:**

```json theme={null}
{
  "items": [
    {
      "id": "689b1f77bcf86cd799439031",
      "ticket": "507f1f77bcf86cd799439022",
      "type": "FEEDBACK_UPDATED",
      "data": {
        "type": "STATUS",
        "value": "INPROGRESS"
      },
      "user": {
        "id": "507f1f77bcf86cd799439012",
        "email": "support@example.com",
        "firstName": "John",
        "lastName": "Doe"
      },
      "bot": false,
      "createdAt": "2026-08-07T10:30:00.000Z",
      "ticketHistoryRow": true
    },
    {
      "id": "689b1f77bcf86cd799439032",
      "ticket": "507f1f77bcf86cd799439022",
      "type": "FEEDBACK_UPDATED",
      "data": {
        "type": "PROCESSING_USER",
        "value": {
          "id": "507f1f77bcf86cd799439012",
          "firstName": "John",
          "lastName": "Doe"
        }
      },
      "fallbackUser": { "username": "System" },
      "bot": false,
      "createdAt": "2026-08-07T10:31:00.000Z",
      "ticketHistoryRow": true
    }
  ],
  "truncated": false
}
```

Key details:

* Entries are returned oldest first. The endpoint is not paginated; `limit` defaults to 1000 (max 5000) and `truncated` is `true` when the ticket has more entries than `limit`.
* `data.type` identifies what changed (`STATUS`, `PROCESSING_USER`, `PROCESSING_TEAM`, `PRIORITY`, `TYPE`, `TAGS_ADDED`, `TAGS_REMOVED`, `TITLE`, `DUE_DATE`, ...) and `data.value` carries the new value — for status changes, the status key of the target Kanban lane.
* History entries are retained for 180 days. If you need a longer record, fetch and persist them on your side.

<Warning>
  Prior to August 2026, these entries were also returned by `GET /v3/messages` as `FEEDBACK_UPDATED` messages. That endpoint now returns conversation messages only — integrations that reconstruct status history from `/v3/messages` should switch to `/v3/tickets/{ticketId}/history`, which returns the same entry shape.
</Warning>

## Uploading Images for Help Center Articles

Help center article `content` is rich text (TipTap JSON). Images inside an article are `image` nodes that reference a hosted image URL, so adding screenshots via the API is a two-step flow: upload each image to get a permanent CDN URL, then reference those URLs in the article content.

### Step 1: Upload the Image

Send the file as `multipart/form-data` in a form field named `file` (up to 100 MB).

**Endpoint:** `POST /v3/uploads`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/uploads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -F "file=@./screenshots/settings-page.png"
```

**Response:**

```json theme={null}
{
  "success": true,
  "fileUrl": "https://staticfiles.gleap.io/p507f191e810c19729de860ea/20260810093015_4821.png"
}
```

If your images are already hosted at a public URL, you can import them instead of re-uploading. The server downloads the image, validates that it really is one (PNG, JPEG, GIF, WebP, SVG or BMP), and stores a copy on the Gleap CDN:

**Endpoint:** `POST /v3/uploads/from-url`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/uploads/from-url \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://cdn.example.com/screenshots/settings-page.png" }'
```

### Step 2: Reference the Images in the Article Content

Use each returned `fileUrl` as the `src` of an `image` node when creating or updating an article:

**Endpoint:** `POST /v3/helpcenter/collections/{helpcenterCollectionId}/articles`

**Request:**

```bash theme={null}
curl -X POST https://api.gleap.io/v3/helpcenter/collections/HELPCENTER_COLLECTION_ID/articles \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Project: YOUR_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Configuring your settings",
    "content": {
      "type": "doc",
      "content": [
        {
          "type": "paragraph",
          "content": [{ "type": "text", "text": "Open the settings page:" }]
        },
        {
          "type": "image",
          "attrs": { "src": "https://staticfiles.gleap.io/p507f191e810c19729de860ea/20260810093015_4821.png" }
        }
      ]
    },
    "isDraft": false
  }'
```

### Bulk Uploads

There is no separate batch endpoint — upload files one request at a time and collect the returned URLs. A small script keeps this manageable:

```bash theme={null}
for f in ./screenshots/*.png; do
  url=$(curl -s -X POST https://api.gleap.io/v3/uploads \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Project: YOUR_PROJECT_ID" \
    -F "file=@$f" | jq -r .fileUrl)
  echo "$f -> $url"
done
```

<Info>
  Uploaded files are stored permanently on the Gleap CDN and the returned URLs are stable, so you can safely reference them from any number of articles. See the [Help center articles endpoints](/api-reference/help-center-articles/create-a-new-article) for the full article schema.
</Info>
