# Topics API

Create and manage monitoring topics via REST. All endpoints require a Bearer API key.

Source: https://ayewatch.ai/documentation/topics

## Scope

These endpoints see only the topics created through the API. Topics you created in the AyeWatch app
aren't returned by the list endpoint, and requesting one by ID returns `404`. Updates for
API-created topics are delivered by [webhook](https://ayewatch.ai/documentation/webhooks) — configure an
endpoint or those updates have nowhere to go.

## Topic types (auto-detected from `name`)

- `web_page` — if `name` is a valid HTTP or HTTPS URL, AyeWatch monitors that specific page.
- `subject` — if `name` is plain text, AyeWatch monitors that keyword/subject across the internet.

## Endpoints

| Method | Path | Description |
| --- | --- | --- |
| `POST` | `/api/v1/topics` | Create a topic |
| `GET` | `/api/v1/topics` | List topics (paginated) |
| `GET` | `/api/v1/topics/:id` | Get a topic |
| `PUT` | `/api/v1/topics/:id` | Update a topic |
| `DELETE` | `/api/v1/topics/:id` | Delete a topic |

## POST /api/v1/topics

Create a new monitoring topic.

Active topics are limited by your plan's monitoring capacity. Accounts also have a default storage
limit of 3,000 topics, counting every topic you have — active or paused, created through the API or
in the app.

### Request Body (JSON)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | A valid URL (e.g. "https://openai.com/news") to monitor a page, or plain text (e.g. "OpenAI announcements") to monitor a subject. Topic type is auto-detected. |
| `interval` | string | Yes | Check interval. One of: "0_5_hours", "1_hour", "6_hours", "12_hours", "1_day", "2_days", "3_5_days", "7_days", "14_days", "30_days", "182_days", "365_days". Your plan must unlock the interval you choose. |
| `description` | string | No | What should alert you. Describe the change you care about, e.g. "Tell me when a new AI model drops." |
| `is_active` | boolean | No | Whether to start monitoring immediately. Default: true. |
| `verification_level` | string | No | How much corroboration is required before you're alerted: "instant", "balanced", or "verified". Defaults to "instant" for pages and "balanced" for subjects. |
| `triggers` | array | No | Precise conditions to alert on, instead of relying on the description alone. See Triggers below. Max 4. |

### Triggers (optional)

A trigger states a condition in structured form. When you supply them, AyeWatch still falls back to
interpreting your `description` for anything the triggers don't cover.

- `entity` — what is being watched, e.g. "GPT-5".
- `attribute` — the property of it, e.g. "price".
- `op` — one of `<`, `<=`, `>`, `>=`, `=`, `changed`, `crossed_above`, `crossed_below`.
- `value` — must be numeric for the comparison operators (everything except `changed`).
- `source_url` — optional, restricts the trigger to one source.

Example — alert on a precise condition:

```bash
curl -X POST https://ayewatch.ai/api/v1/topics \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "NVIDIA H100 pricing",
    "interval": "6_hours",
    "verification_level": "verified",
    "triggers": [
      {
        "entity": "H100 80GB",
        "attribute": "price",
        "op": "<",
        "value": 25000,
        "value_type": "number"
      }
    ]
  }'
```

Example — monitor a URL:

```bash
curl -X POST https://ayewatch.ai/api/v1/topics \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "https://openai.com/news",
    "interval": "1_hour"
  }'
```

Example — monitor a subject / keyword:

```bash
curl -X POST https://ayewatch.ai/api/v1/topics \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "OpenAI product announcements",
    "interval": "1_day"
  }'
```

Response — 201 Created:

```json
{
  "data": {
    "id": 1042,
    "name": "https://openai.com/news",
    "description": null,
    "is_active": true,
    "interval": "1_hour",
    "topic_type": "web_page",
    "schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
    "next_run_at": null,
    "created_at": "2026-08-03T12:00:00Z",
    "schedule_status": "synced"
  }
}
```

### About `schedule_status`

Returned on create, update, and delete. The topic itself is already saved when you get a `2xx` —
this field only tells you whether its monitoring schedule has finished being applied.

- `synced` — the schedule is live. Nothing more to do.
- `pending` — the change is queued and will be applied automatically within a few minutes. This is
  not an error and does not need a retry; the topic is saved either way.

## GET /api/v1/topics

List all API-created topics for the authenticated user, paginated.

### Query Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | number | No | Page number. Default: 1. |
| `page_size` | number | No | Results per page. Max: 100. Default: 20. |
| `is_active` | boolean | No | Filter by active status. Pass "true" or "false". |
| `interval` | string | No | Filter by interval. One of: "1_hour", "6_hours", etc. Legacy values on older topics are also accepted as a filter. |
| `created_after` | string (ISO 8601) | No | Only topics created after this datetime. |
| `created_before` | string (ISO 8601) | No | Only topics created before this datetime. |

Request:

```bash
curl "https://ayewatch.ai/api/v1/topics?page=1&page_size=10&is_active=true" \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY"
```

Response — 200 OK:

```json
{
  "data": [
    {
      "id": 1042,
      "name": "https://openai.com/news",
      "topic_type": "web_page",
      "description": null,
      "is_active": true,
      "interval": "1_hour",
      "schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
      "next_run_at": null,
      "created_at": "2026-03-08T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 10,
    "has_more": false
  }
}
```

## GET /api/v1/topics/:id

Retrieve a single topic by ID.

Request:

```bash
curl https://ayewatch.ai/api/v1/topics/1042 \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY"
```

Response — 200 OK:

```json
{
  "data": {
    "id": 1042,
    "name": "https://openai.com/news",
    "topic_type": "web_page",
    "description": null,
    "is_active": true,
    "interval": "1_hour",
    "schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
    "next_run_at": null,
    "created_at": "2026-03-08T12:00:00Z"
  }
}
```

## PUT /api/v1/topics/:id

Update a topic. Send only the fields you want to change.

### Request Body (JSON) — all fields optional

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | New name or URL. Topic type is re-detected automatically. |
| `description` | string | No | New description. |
| `interval` | string | No | New check interval. One of: "1_hour", "6_hours", etc. Your plan must unlock the interval you choose. |
| `is_active` | boolean | No | Enable or disable the topic. |
| `verification_level` | string | No | New verification level: "instant", "balanced", or "verified". |
| `triggers` | array | No | Replaces the existing triggers. Send an empty array to clear them; omit the field to leave them untouched. |

The request must contain at least one of these fields. Unknown fields are rejected with a `400`
rather than silently ignored.

Request:

```bash
curl -X PUT https://ayewatch.ai/api/v1/topics/1042 \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"interval": "6_hours", "is_active": false}'
```

Response — 200 OK:

```json
{
  "data": {
    "id": 1042,
    "name": "https://openai.com/news",
    "description": null,
    "is_active": false,
    "interval": "6_hours",
    "topic_type": "web_page",
    "schedule_arn": null,
    "next_run_at": null,
    "created_at": "2026-03-08T12:00:00Z",
    "schedule_status": "synced"
  }
}
```

## DELETE /api/v1/topics/:id

Permanently delete a topic and its schedule. This action cannot be undone.

Request:

```bash
curl -X DELETE https://ayewatch.ai/api/v1/topics/1042 \
  -H "Authorization: Bearer aw_live_YOUR_API_KEY"
```

Response — 200 OK:

```json
{
  "data": {
    "deleted": true,
    "schedule_status": "synced"
  }
}
```
