# Pixicular — Agent Integration Guide

> Technical instructions for AI agents and autonomous systems that want to call the
> Pixicular image-analysis API programmatically. Pixicular is a REST API that analyzes
> any photo and returns structured JSON — object/scene labels, age estimation, facial
> emotions, content moderation, and OCR text — from a single endpoint.

Pixicular publishes two machine-readable files at its domain root, with distinct roles:

- [`/llms.txt`](https://www.pixicular.com/llms.txt) — a concise, curated index of the
  site (a "sitemap for LLMs"): what Pixicular is and where the key pages live.
- `/agents.md` — **this file**: the technical operating manual for autonomous agents
  that need to authenticate and call the API. If `llms.txt` is the business card,
  `agents.md` is the integration handbook.

## Quick reference

| Item | Value |
| --- | --- |
| API base URL | `https://api.pixicular.com` |
| Version prefix | `/v1` (all endpoints live under `/v1/`) |
| Authentication | `Authorization: Bearer <api_key>` |
| API key format | `apd_live_…` (production) · `apd_test_…` (development) |
| Get an API key | https://www.pixicular.com/dashboard → **API Keys** |
| Detection endpoints | `POST /v1/detect` · `POST /v1/detect-from-url` |
| History endpoints | `GET /v1/history` · `GET /v1/history/:requestId` |
| Request body | `multipart/form-data` (file) or `application/json` (URL) |
| Max image size | 10 MB |
| Image dimensions | 100×100 to 4096×4096 px |
| Accepted MIME types | `image/jpeg`, `image/png`, `image/webp`, `image/avif`, `image/tiff` |
| Rate limit | 60 req/min (detection), 600 req/min (history) |
| Billing unit | 1 credit per service, per image (an "operation") |
| Human docs | https://www.pixicular.com/documentation |
| Support | support@pixicular.com |

## Authentication

Every request must include a Bearer token in the `Authorization` header:

```
Authorization: Bearer apd_live_your_api_key_here
```

- Create and revoke keys in the dashboard at
  https://www.pixicular.com/dashboard (**API Keys**).
- `apd_test_…` keys behave identically to `apd_live_…` keys but are tracked
  separately — use them while developing, and `apd_live_…` keys in production.
- Keep keys server-side. Never embed an API key in client-side code, a public
  repository, or a prompt that may be logged.

A missing or malformed key returns `401 Unauthorized`.

## Detection services

Pass a comma-separated list of service IDs in the `services` field. Multiple services
can run on a single image in one request; **each service costs 1 credit**.

| Service ID | Description |
| --- | --- |
| `detect-labels` | Objects, scenes, and activities with confidence scores and category tags |
| `detect-age` | Estimated age range for every face detected |
| `detect-face-emotions` | Confidence scores for 8 emotions (HAPPY, SAD, ANGRY, SURPRISED, DISGUSTED, CALM, CONFUSED, FEAR) per face |
| `detect-moderation` | Flags unsafe/sensitive content (nudity, violence, drugs, hate symbols); returns hierarchical labels |
| `detect-text` | OCR — extracts full lines of text found in the image |

Example: `services=detect-labels,detect-age` runs two services and costs 2 credits.

## `POST /v1/detect` — analyze an uploaded file

Send the image as `multipart/form-data` with a `file` part and a `services` field.

```bash
curl -X POST "https://api.pixicular.com/v1/detect" \
  -H "Authorization: Bearer apd_live_your_api_key_here" \
  -F "services=detect-age" \
  -F "file=@/path/to/image.jpg"
```

## `POST /v1/detect-from-url` — analyze an image by URL

Send `application/json` with a `url` and a `services` string. Pixicular downloads the
image server-side, so the URL must be publicly reachable.

```bash
curl -X POST "https://api.pixicular.com/v1/detect-from-url" \
  -H "Authorization: Bearer apd_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "services": "detect-age",
    "url": "https://example.com/image.jpg"
  }'
```

### Detection response

Both detection endpoints return the same shape. Each requested service appears as a key
under `services`:

```json
{
  "success": true,
  "requestId": "req_wUKl0im7IZg4bCefnE",
  "services": {
    "detect-age": {
      "faces": [
        { "ageRange": { "low": 22, "high": 28 }, "ageEstimate": 25, "confidence": 99.9 }
      ]
    }
  },
  "photo": { "id": "photo_Dy2csYO9nhYgdDxn9B", "status": "COMPLETED" },
  "creditCost": 1,
  "processingTimeMs": 1250,
  "processedAt": "2025-12-31T23:59:59.002Z"
}
```

Per-service result shapes:

```json
{ "detect-labels":        { "labels": [ { "name": "Person", "confidence": 99.8, "categories": ["People"] } ] } }
{ "detect-age":           { "faces":  [ { "ageRange": { "low": 25, "high": 35 }, "ageEstimate": 30, "confidence": 98.4 } ] } }
{ "detect-face-emotions": { "faces":  [ { "faceConfidence": 99.9, "emotions": [ { "type": "HAPPY", "confidence": 97.2 } ] } ] } }
{ "detect-moderation":    { "detected": true, "labels": [ { "name": "Suggestive", "parentName": "", "confidence": 90.5 } ] } }
{ "detect-text":          { "detections": [ { "detectedText": "Hello World", "type": "LINE", "confidence": 99.1 } ] } }
```

## `GET /v1/history` — list past results

Returns a paginated list of your detection requests.

```bash
curl "https://api.pixicular.com/v1/history?page=1&perPage=50" \
  -H "Authorization: Bearer apd_live_your_api_key_here"
```

| Query param | Type | Default | Description |
| --- | --- | --- | --- |
| `page` | integer | `1` | Page number |
| `perPage` | integer | `50` | Results per page (max 100) |

## `GET /v1/history/:requestId` — fetch one result

```bash
curl "https://api.pixicular.com/v1/history/req_wUKl0im7IZg4bCefnE" \
  -H "Authorization: Bearer apd_live_your_api_key_here"
```

Use the `requestId` returned by a detection call to retrieve its stored result later.

## Errors

The API uses standard HTTP status codes and a consistent JSON error body:

```json
{ "statusCode": 400, "error": "Bad Request", "message": "..." }
```

| Status | Meaning | Common causes |
| --- | --- | --- |
| `400` | Bad Request | Missing `file`/`url`/`services`, invalid service ID, unsupported file type, wrong `Content-Type` |
| `401` | Unauthorized | Missing, malformed, invalid, or expired API key |
| `422` | Unprocessable Entity | `/v1/detect-from-url` could not download the image, or the remote file is too large / an unsupported type |
| `429` | Too Many Requests | Rate limit (60 req/min) exceeded, or monthly usage cap reached — back off and retry |
| `500` | Internal Server Error | Unexpected server-side failure — retry with backoff |

## Recommended agent flow

```
1. Read the API key from a secure secret store (never hard-code it).
2. Decide which services you need and build a comma-separated `services` string.
3. Send the image:
     - have a local file?  -> POST /v1/detect          (multipart/form-data)
     - have a public URL?  -> POST /v1/detect-from-url  (application/json)
4. On HTTP 200, read results from response.services[<serviceId>].
5. On HTTP 429, wait (respect Retry-After if present) and retry with exponential backoff.
6. On HTTP 4xx other than 429, fix the request — do not blindly retry.
7. (Optional) Persist response.requestId to fetch the result later via /v1/history/:requestId.
```

## Rules and best practices

- **Batch services in one request.** Requesting `detect-age,detect-labels` together is
  one round-trip; each service is still billed as 1 credit, but you save latency.
- **Validate before sending.** Reject images over 10 MB or outside the accepted MIME
  types client-side to avoid wasted `400`/`422` responses.
- **Respect rate limits.** Cap detection traffic at 60 requests/minute per key and use
  exponential backoff on `429`.
- **Use test keys in non-production.** Develop and run CI against `apd_test_…` keys.
- **Treat results as probabilistic.** Every detection includes a `confidence` score;
  threshold on it rather than assuming certainty.

## Limits and pricing

- Plans (monthly included operations): Developer (free, 100) · Launch ($25, 1,000) ·
  Scale ($99, 10,000) · Business ($299, 100,000) · Enterprise (custom).
- An **operation** is one service run on one image; an image with 3 services = 3
  operations. See https://www.pixicular.com/pricing for current details and overage rates.

## Reference links

- [API documentation](https://www.pixicular.com/documentation) — full reference with Node.js & Python examples
- [llms.txt](https://www.pixicular.com/llms.txt) — site index for LLMs
- [Pricing](https://www.pixicular.com/pricing) — plans and overage rates
- [Live demo](https://www.pixicular.com/demo) — try the API in the browser, no account needed
- [Dashboard](https://www.pixicular.com/dashboard) — manage API keys and view usage
- Support: support@pixicular.com
