---
title: API Reference
description: Complete API documentation for the Ascently sync server
---

Complete reference for all sync server endpoints.

## Authentication

All endpoints require a bearer token in the `Authorization` header:

```
Authorization: Bearer your-auth-token
```

Unauthorized requests return `401 Unauthorized`.

## Endpoints

### Health Check

**`GET /health`**

Check if the server is running.

**Response:**
```json
{
  "status": "ok",
  "version": "2.0.0"
}
```

### Full Sync - Download

**`GET /sync`**

Download the entire dataset from the server.

**Response:**
```json
{
  "exportedAt": "2024-01-15T10:30:00.000Z",
  "version": "2.0",
  "formatVersion": "2.0",
  "gyms": [...],
  "problems": [...],
  "sessions": [...],
  "attempts": [...],
  "deletedItems": [...]
}
```

Returns `200 OK` with the backup data, or `404 Not Found` if no data exists.

### Full Sync - Upload

**`POST /sync`**

Upload your entire dataset to the server. This overwrites all server data.

**Request Body:**
```json
{
  "exportedAt": "2024-01-15T10:30:00.000Z",
  "version": "2.0",
  "formatVersion": "2.0",
  "gyms": [...],
  "problems": [...],
  "sessions": [...],
  "attempts": [...],
  "deletedItems": [...]
}
```

**Response:**
```
200 OK
```

### Delta Sync

**`POST /sync/delta`**

Sync only changed data since your last sync. Much faster than full sync.

**Request Body:**
```json
{
  "lastSyncTime": "2024-01-15T10:00:00.000Z",
  "gyms": [...],
  "problems": [...],
  "sessions": [...],
  "attempts": [...],
  "deletedItems": [...]
}
```

Include only items modified after `lastSyncTime`. The server merges your changes with its data using last-write-wins based on `updatedAt` timestamps.

**Response:**
```json
{
  "serverTime": "2024-01-15T10:30:00.000Z",
  "gyms": [...],
  "problems": [...],
  "sessions": [...],
  "attempts": [...],
  "deletedItems": [...]
}
```

Returns only server items modified after your `lastSyncTime`. Save `serverTime` as your new `lastSyncTime` for the next delta sync.

### Image Upload

**`POST /images/upload?filename={name}`**

Upload an image file.

**Query Parameters:**
- `filename`: Image filename (e.g., `problem_abc123_0.jpg`)

**Request Body:**
Binary image data (JPEG, PNG, GIF, or WebP)

**Response:**
```
200 OK
```

### Image Download

**`GET /images/download?filename={name}`**

Download an image file.

**Query Parameters:**
- `filename`: Image filename

**Response:**
Binary image data with appropriate `Content-Type` header.

Returns `404 Not Found` if the image doesn't exist.

## Notes

- All timestamps are ISO 8601 format with milliseconds
- Active sessions (status `active`) are excluded from sync
- Images are stored separately and referenced by filename
- The server stores everything in a single `ascently.json` file
- No versioning or history - last write wins
