---
title: "Create a watch"
method: POST
path: "/watches"
---

# Create a watch

`POST /watches`

## Request

- Base URL: `https://firstsited.com/api/v1`
- URL: `https://firstsited.com/api/v1/watches`
- Auth: HTTP bearer

A standing watch over newly detected launches, delivered by HMAC-signed webhook, Slack webhook or email digest. Technology and keyword counts per watch and total watches are capped by plan.

Requires the `watches` scope. Available on: indie, pro, firehose.

## Request body

- object
  - `techs` string[]: Technologies, matching ANY one of them.
  - `techsAll` string[]: Technologies the launch must ALL carry. Counts toward the per-watch technology allowance.
  - `techsExcluding` string[]: Technologies that disqualify a launch. FREE: never counts toward the allowance, since each one narrows the watch. Means NOT DETECTED rather than not installed, so only reliably detected technologies may be excluded.
  - `keywords` string[]: Words the launch's name, tagline, page title, first heading or meta description must carry, matching ANY one of them. Whole words, case-insensitive; a multi-word entry is a phrase. Each must be 3 to 60 characters. Capped per watch by the plan (maxKeywordsPerWatch in x-stackscope-plans), on its own allowance rather than the technologies', so a technology and a keyword fit together on every plan. A keyword so common that a month of it would exceed the plan's launch ceiling is refused at creation with the estimate that says so.
  - `categories` string[]: Product categories, matching any one.
  - `countries` string[]: ISO2 country codes, matching any one.
  - `near` string: One circle's place: a town or city name, a postcode, or lat,lng. A name that fits several places takes the biggest, with the first of countries first. Needs radius.
  - `radius` string: The circle's radius: 30mi or 50km, a bare number being km. From 5 to 248 miles (8 to 400 km).
  - `circles` object[]: Up to three circles, each {near, radius}, instead of near and radius. A launch matches if it is in any of them.
    - `near` string
    - `radius` string
  - `indie` boolean: Restrict to launches classed as indie.
  - `hasEmail` boolean: Only launches whose site publishes a role email address (true), or only those that do not (false). Omit for no filter. Needs the contacts scope; refused with 400 without it.
  - `hasContactUrl` boolean: Only launches whose site publishes its own contact page (true), or only those that do not (false). Omit for no filter; set both to require both. Needs the contacts scope; refused with 400 without it.
  - `channel` 'webhook' | 'slack' | 'email' | 'portal': Delivery channel.
  - `webhookUrl` string: HTTPS endpoint; required for webhook and slack.
  - `digestCadence` 'instant' | 'daily' | 'weekly': Delivery cadence.

## Response `200`

Success.

- object

## Other responses

- `400`: A required parameter is missing or malformed.
- `401`: No usable key. While the API is unannounced this is masked as 404.
- `403`: The key or plan does not carry the required scope.
- `429`: Quota exhausted (`monthly_credits_exhausted` or `distinct_launch_ceiling_reached`), or the per-key rate limit was exceeded, which returns a plain-text body rather than JSON.

## Changes

- **2026-10-20** `01db728020dd`: 3 info
  - added the new optional request property `circles`
  - added the new optional request property `near`
  - added the new optional request property `radius`

[Operation history](https://skmtc.dev/stackscope/apis/firstsited-api/changes/watches/post.md)

---

[API](https://skmtc.dev/stackscope/apis/firstsited-api.md) · [All operations](https://skmtc.dev/stackscope/apis/firstsited-api/llms.txt) · [OpenAPI document](https://skmtc.dev/stackscope/apis/firstsited-api/revisions/01db728020dd?raw)
