# 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 manage every monitor in your account, including monitors created on the website or mobile app.
API-created monitors appear in the same monitor list and follow your account's notification preferences.
The same plan limits and monitoring credits apply across all platforms. API calls do not have a separate bill.
Configure a [webhook](https://ayewatch.ai/documentation/webhooks) in settings or with `PUT /api/v1/webhook` to receive update notifications in your application.

## Topic types (on creation, 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 active-topic limit and allowed intervals, and turning a topic
on needs at least one monitoring credit. 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 | No | Required unless template or web_page_urls is supplied. 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 | No | Required for custom monitoring unless template supplies it. 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. |
| `type` | string | No | "subject" or "web_page". Detected from name on creation if omitted; preserved on edits. |
| `web_page_urls` | string[] | No | Pages to monitor together. Replaces the source list. Your plan's page limit applies. |
| `monitoring_mode` | string | No | "auto" or "custom". Defaults to custom. |
| `auto_min_interval`, `auto_max_interval` | string or null | No | Interval bounds for automatic monitoring. |
| `timezone` | string | No | IANA timezone, for example Asia/Kolkata. |
| `template` | object | No | Template selection: id, version, inputs, interval. Keep the template id on edits; do not mix with direct configuration overrides. |
| `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",
    "created_at": "2026-08-03T12:00:00Z"
  }
}
```

Create, read, list, and update responses contain only id, name, description, interval, is_active, and created_at.
Use id to fetch, edit, or delete the monitor. is_active is true for an active monitor and false for a paused monitor.
Successful changes are saved immediately; monitoring may take a few minutes to start.

## GET /api/v1/topics

List all monitors for the authenticated account, 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",
      "description": null,
      "is_active": true,
      "interval": "1_hour",
      "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",
    "description": null,
    "is_active": true,
    "interval": "1_hour",
    "created_at": "2026-03-08T12:00:00Z"
  }
}
```

Responses contain the monitor's basic details.
Keep any template selection and inputs in your integration if you need to edit them later.

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

Update a topic. Send only the fields you want to change.
Omitted settings are preserved. Name, description, or source changes clear generated alert rules unless replacement triggers are supplied.
Use template inputs to edit template monitors. is_active and timezone can be updated independently.
List account monitors and use a returned ID to edit a monitor created on the website or mobile app.

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

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | New subject name or first page URL. Other page URLs are preserved. Use type to change the monitor type. |
| `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". |
| `type` | string | No | "subject" or "web_page". Detected from name on creation if omitted; preserved on edits. |
| `web_page_urls` | string[] | No | Pages to monitor together. Replaces the source list. Your plan's page limit applies. |
| `monitoring_mode` | string | No | "auto" or "custom". Defaults to custom. |
| `auto_min_interval`, `auto_max_interval` | string or null | No | Interval bounds for automatic monitoring. |
| `timezone` | string | No | IANA timezone, for example Asia/Kolkata. |
| `template` | object | No | Template selection: id, version, inputs, interval. Keep the template id on edits; do not mix with direct configuration overrides. |
| `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",
    "created_at": "2026-03-08T12:00:00Z"
  }
}
```

## 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
  }
}
```
