# Use the Server API

Source: https://frameleaf.app/docs/api/overview/

The Frameleaf Server API lets your scripts and tools upload media, organize albums, search your library and automate administration on your own server. Create a scoped API key, try the examples below, then explore the full reference.

[Browse endpoints](https://frameleaf.app/docs/api/reference/) · [Browse schemas](https://frameleaf.app/docs/api/schemas/) · [Download the OpenAPI specification](https://frameleaf.app/api/frameleaf-openapi.json)

## Connect to your server

Use your Frameleaf address followed by `/api`, for example `https://photos.example.com/api`. The API uses your server's accounts and access rules. These pages cover the self-hosted endpoints for API-key integrations.

The reference shows its API version, and `GET /api/server/version` returns your running server version, so you can match the two.

## Create an API key

1. Sign in to the Frameleaf web app.
2. Open **Settings → Access & security → API keys**.
3. Create a key with a descriptive name and only the permissions your script needs.
4. Copy the key when it's shown and store it privately. Delete it when you no longer need the integration.

Send the key in the `x-api-key` header, and keep it out of public URLs, browser scripts and source repositories. A key has at most the access of the account that owns it, and administrative operations need administrator access.

For the examples below, set `FRAMELEAF_API_URL` to your server address including `/api`, and provide `FRAMELEAF_API_KEY` through your shell's secret or environment facility.

## Read your albums

Requires `album.read`.

```bash
curl --fail-with-body \
  --header "x-api-key: $FRAMELEAF_API_KEY" \
  "$FRAMELEAF_API_URL/albums"
```

See [Albums](https://frameleaf.app/docs/api/reference/albums/) for ownership filters, album creation and sharing.

## Upload a photo

Requires `asset.upload`. Uploads use multipart form data; let your HTTP client set the boundary. Use the file's real creation and modification timestamps in ISO 8601 format.

```bash
curl --fail-with-body \
  --header "x-api-key: $FRAMELEAF_API_KEY" \
  --form 'assetData=@photo.jpg' \
  --form 'fileCreatedAt=2026-10-01T12:30:00.000Z' \
  --form 'fileModifiedAt=2026-10-01T12:30:00.000Z' \
  "$FRAMELEAF_API_URL/assets"
```

A new upload returns `201`; a duplicate returns `200`. Use the returned asset ID in later requests. See [Assets](https://frameleaf.app/docs/api/reference/assets/#uploadAsset) for the complete request and response. For folders and large imports, the [Frameleaf CLI](https://frameleaf.app/docs/admin/api-and-cli/) is usually easier than writing an uploader.

## Read requests and responses

Each endpoint page lists its HTTP method, path, authentication, API-key permission and parameter locations. Replace `{id}` in a path with the actual identifier. JSON requests need `Content-Type: application/json`; file uploads use multipart form data.

Schema links explain nested objects, allowed enum values, formats and required fields. An omitted field and a field set to `null` can mean different things. Keep identifiers as strings, and follow each endpoint's pagination fields to page through large results.

## Handle failures

| Status | What to do |
| --- | --- |
| `400` | Check required fields, formats and allowed values. |
| `401` | Check that the key is valid and the request includes its header. |
| `403` | Check the key's permissions and the owning account's access. |
| `404` | Check the ID, route and server version. A resource may be unavailable to your account. |
| `409` | Refresh current state before retrying a conflicting update. |
| `413` | Check server and reverse-proxy upload limits. |
| `429` | Respect `Retry-After` when returned and slow your requests. |
| `5xx` | Check server health; retry reads with a delay. Check the result of a write before repeating it. |

For destructive operations such as permanent deletion and database restoration, test your script on a small sample first, keep backups, and check a write's result before retrying it.
