# Introduction

Welcome to the **Eagle Web API V2** documentation. This API allows any HTTP client — scripts, apps, browser extensions, automation tools — to interact with the Eagle application over a local HTTP server.

{% hint style="info" %}
**Looking for the V1 API?** The legacy V1 API documentation is available at <https://api.eagle.cool/>. V2 offers a more comprehensive feature set based on the Plugin API capabilities.
{% endhint %}

{% hint style="warning" %}
**Version Requirement:** The V2 Web API requires **Eagle 4.0 Build 21** or later.
{% endhint %}

***

## Web API vs Plugin API <a href="#web-api-vs-plugin-api" id="web-api-vs-plugin-api"></a>

Eagle provides two different APIs for developers:

* **Web API** (this documentation) — A RESTful HTTP API for building **external** tools, services, scripts, or integrations that communicate with Eagle from outside the application. Use this if you are building browser extensions, automation workflows, third-party apps, or any tool that runs independently of Eagle.
* [**Plugin API**](https://developer.eagle.cool/plugin-api) — A JavaScript API for building plugins that run **inside** Eagle. Plugins have direct access to Eagle's UI, can create custom panels, respond to user interactions, and deeply integrate with the application. Use this if you want to extend Eagle's built-in functionality.

|               | Web API                             | Plugin API                                                                 |
| ------------- | ----------------------------------- | -------------------------------------------------------------------------- |
| Runs          | Outside Eagle (any HTTP client)     | Inside Eagle (as a plugin)                                                 |
| Protocol      | HTTP REST                           | JavaScript API                                                             |
| Use case      | External tools, scripts, automation | Eagle plugins, custom panels, UI extensions                                |
| Documentation | This site                           | [developer.eagle.cool/plugin-api](https://developer.eagle.cool/plugin-api) |

***

## What's New in V2 <a href="#whats-new" id="whats-new"></a>

The V2 API (`/api/v2/...`) provides significantly more endpoints than V1 (`/api/...`), including:

* **Full-text search** with advanced query syntax (AND, OR, NOT)
* **AI semantic search** — search by text description or image similarity
* **Tag management** — create, rename, merge tags and manage tag groups
* **Folder management** — create, move, and organize folders
* **Automatic pagination** — all list endpoints are paginated by default to ensure performance
* [**API Playground**](https://developer.eagle.cool/web-api/get-started/playground) — built-in interactive tool to test all endpoints directly in your browser

***

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

Eagle is a local application — the API server starts automatically when the Eagle app is opened. **You must have Eagle running** before you can access any API endpoint.

***

## Base URL <a href="#base-url" id="base-url"></a>

```
http://localhost:41595/api/v2/
```

The Eagle API server runs on port **41595** by default. All V2 endpoints are prefixed with `/api/v2/`.

***

## Authentication <a href="#authentication" id="authentication"></a>

### Local Access (localhost)

If you are making requests from the same machine where Eagle is running, **no authentication is required**. Requests from `localhost`, `127.0.0.1`, or `0.0.0.0` are automatically trusted — you can start calling the API right away.

```javascript
// Local access — no token needed
await fetch("http://localhost:41595/api/v2/library/info").then(r => r.json());
```

### Remote Access (LAN / Network)

If you want to call the Eagle API from another device on your local network (e.g., a phone, tablet, or another computer), you must include an **API Token** with every request.

#### How to Get Your API Token

1. Open Eagle and go to **Preferences** (Settings)
2. Click on **Developer** in the left sidebar
3. Your **API Token** is displayed at the top of the page
4. Click the copy button next to the token to copy it to your clipboard

You can also click **Regenerate Token** to generate a new token at any time. Note that regenerating a token will invalidate the previous one.

#### Using the Token

Append the `token` parameter to any request URL:

```javascript
// Remote access with token
const TOKEN = "f366c476-7533-4f33-b454-2bc720a1d0ea";

await fetch(`http://192.168.1.100:41595/api/v2/library/info?token=${TOKEN}`)
    .then(r => r.json());

// Also works with POST requests
await fetch(`http://192.168.1.100:41595/api/v2/item/get?token=${TOKEN}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ tags: ["design"], limit: 20 })
}).then(r => r.json());
```

{% hint style="warning" %}
**Keep your token private.** Anyone with your API Token can access and modify your Eagle library over the network. Do not share it publicly or commit it to version control.
{% endhint %}

***

## Response Format <a href="#response-format" id="response-format"></a>

All endpoints return responses in [JSend](https://github.com/omniti-labs/jsend) format:

**Success:**

```json
{
    "status": "success",
    "data": { ... }
}
```

**Error:**

```json
{
    "status": "error",
    "message": "Error description"
}
```

***

## Pagination <a href="#pagination" id="pagination"></a>

All list endpoints (`item/get`, `item/query`, `folder/get`, `tag/get`, etc.) return paginated results by default.

| Parameter | Type    | Default | Max    | Description               |
| --------- | ------- | ------- | ------ | ------------------------- |
| `offset`  | Integer | `0`     | —      | Number of items to skip   |
| `limit`   | Integer | `50`    | `1000` | Number of items to return |

**Paginated response:**

```json
{
    "status": "success",
    "data": {
        "data": [ ... ],
        "total": 8500,
        "offset": 100,
        "limit": 50
    }
}
```

* `total` — Total number of matching items (before pagination)
* `offset` — The offset used
* `limit` — The limit used
* `data` — The paginated result array

**Example: Iterating through all items**

```javascript
// Page 1: items 0-49
const page1 = await fetch("http://localhost:41595/api/v2/item/get?limit=50").then(r => r.json());

// Page 2: items 50-99
const page2 = await fetch("http://localhost:41595/api/v2/item/get?offset=50&limit=50").then(r => r.json());

// Continue until data.data.length < limit (last page)
```

***

## Quick Start <a href="#quick-start" id="quick-start"></a>

```javascript
// Check if Eagle is running
await fetch("http://localhost:41595/api/v2/app/info").then(r => r.json());

// Get library info
await fetch("http://localhost:41595/api/v2/library/info").then(r => r.json());

// List first 50 items
await fetch("http://localhost:41595/api/v2/item/get").then(r => r.json());

// Search items by tag
await fetch("http://localhost:41595/api/v2/item/get", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ tags: ["design"] })
}).then(r => r.json());

// Full-text search
await fetch("http://localhost:41595/api/v2/item/query", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query: "sunset landscape" })
}).then(r => r.json());

// AI semantic search
await fetch("http://localhost:41595/api/v2/aiSearch/searchByText", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query: "an orange cat", options: { limit: 10 } })
}).then(r => r.json());
```

***

## API Sections <a href="#api-sections" id="api-sections"></a>

| Section                                                         | Description                          |
| --------------------------------------------------------------- | ------------------------------------ |
| [Item](https://developer.eagle.cool/web-api/api/item)           | Query, add, modify, and manage items |
| [Folder](https://developer.eagle.cool/web-api/api/folder)       | Create, list, and organize folders   |
| [Tag](https://developer.eagle.cool/web-api/api/tag)             | List, rename, and merge tags         |
| [Tag Group](https://developer.eagle.cool/web-api/api/tag-group) | Manage tag groups                    |
| [Library](https://developer.eagle.cool/web-api/api/library)     | Get library metadata                 |
| [App](https://developer.eagle.cool/web-api/api/app)             | Application information              |
| [AI Search](https://developer.eagle.cool/web-api/api/ai-search) | AI semantic & image search           |

***

## CORS <a href="#cors" id="cors"></a>

If you are calling the Eagle API from a webpage (e.g., via a userscript manager like **Tampermonkey** or **Violentmonkey**), standard `fetch` requests may be blocked by the browser's Cross-Origin Resource Sharing (CORS) policy. In this case, use `GM_xmlhttpRequest` instead:

```javascript
GM_xmlhttpRequest({
    method: "GET",
    url: "http://localhost:41595/api/v2/item/get",
    onload: function (response) {
        const data = JSON.parse(response.responseText);
        console.log(data);
    }
});
```

{% hint style="info" %}
This only applies to scripts running inside web pages. If you are calling the API from Node.js, Electron, a browser extension's background script, or directly from DevTools, CORS does not apply and you can use `fetch` normally.
{% endhint %}

***

## Rate Limits <a href="#rate-limits" id="rate-limits"></a>

There are **no rate limits** on API calls. Since the API server runs locally on your machine, all requests are processed directly without any throttling. However, keep in mind that the server's performance depends on your device's hardware — heavy operations on very large libraries may take longer to respond.
