Keywords
Retrieve keyword trend data and managed tracked keyword targets. The GET endpoint returns GSC data or tracked targets depending on the view parameter. POST upserts tracked keywords; DELETE removes them by ID.
/api/v1/sites/:siteId/keywordsKeyword trends and tracked targets
Without ?view=targets returns GSC keyword trend data (impressions, clicks, CTR, position with period-over-period changes). With ?view=targets returns the tracked keyword target list with latest rank data.
Request
curl -X GET \
'https://letoseo.com/api/v1/sites/:siteId/keywords' \
-H 'Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'Path parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
siteId | uuid | required | The site UUID. | — |
Query parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
view | "targets" | optional | Pass "targets" to return the tracked keyword target list instead of GSC trend data. | — |
date_range | "7d" | "28d" | "90d" | optional | Time range for GSC trend data. Ignored when view=targets. | 28d |
limit | integer | optional | Maximum number of results. Max 100. | 25 |
query_filter | string | optional | Substring filter applied to keyword strings. Case-insensitive. Only applies to the default (trends) view. | — |
intent | string | optional | Filter by search intent. Only applies when view=targets. | — |
priority | "money" | "standard" | "long-tail" | optional | Filter by keyword priority. Only applies when view=targets. | — |
sort | string | optional | Column to sort by when view=targets. | keyword |
order | "asc" | "desc" | optional | Sort direction when view=targets. | asc |
Responses
{
"data": [
{
"query": "example keyword",
"impressions": 1240,
"clicks": 62,
"ctr": 0.05,
"position": 7.4,
"impressions_prev": 1100,
"clicks_prev": 55,
"position_prev": 8.1
},
{
"query": "acme tool review",
"impressions": 640,
"clicks": 19,
"ctr": 0.03,
"position": 14.2,
"impressions_prev": 580,
"clicks_prev": 18,
"position_prev": 15
}
],
"_meta": {
"generated_at": "2025-01-15T10:30:00.000Z",
"site_id": "00000000-0000-0000-0000-000000000001"
}
}{
"error": "Site not found"
}/api/v1/sites/:siteId/keywordsAdd or update tracked keywords
Upserts keyword tracking targets for a site. If a keyword already exists (matched on site_id + keyword + location_code + device), its fields are updated. Returns 201 with the upserted rows. Maximum 100 keywords per request; maximum 200 keywords per site.
Request
curl -X POST \
'https://letoseo.com/api/v1/sites/:siteId/keywords' \
-H 'Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"keywords": [
{
"keyword": "example keyword",
"priority": "money",
"tracking_frequency": "daily",
"device": "desktop",
"source": "manual"
},
{
"keyword": "acme tool review"
}
]
}'Path parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
siteId | uuid | required | The site UUID. | — |
Request body (application/json)
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
keywords | KeywordInput[] | required | Array of keyword objects to upsert. Each object must include at least "keyword". | — |
Example
{
"keywords": [
{
"keyword": "example keyword",
"priority": "money",
"tracking_frequency": "daily",
"device": "desktop",
"source": "manual"
},
{
"keyword": "acme tool review"
}
]
}Responses
{
"data": [
{
"id": "00000000-0000-0000-0000-000000000021",
"site_id": "00000000-0000-0000-0000-000000000001",
"keyword": "example keyword",
"priority": "money",
"tracking_frequency": "daily",
"device": "desktop",
"source": "manual",
"search_intent": null,
"location_code": 2840,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
},
{
"id": "00000000-0000-0000-0000-000000000022",
"site_id": "00000000-0000-0000-0000-000000000001",
"keyword": "acme tool review",
"priority": "standard",
"tracking_frequency": "daily",
"device": "desktop",
"source": "manual",
"search_intent": null,
"location_code": 2840,
"created_at": "2025-01-15T10:30:01.000Z",
"updated_at": "2025-01-15T10:30:01.000Z"
}
],
"_meta": {
"generated_at": "2025-01-15T10:30:00.000Z",
"site_id": "00000000-0000-0000-0000-000000000001"
}
}{
"error": "keywords array is required"
}{
"error": "Site not found"
}/api/v1/sites/:siteId/keywordsRemove tracked keywords
Deletes keyword tracking targets by ID. Requires a JSON body with the array of IDs to delete. Returns 204 with an empty body on success. Maximum 100 IDs per request.
Request
curl -X DELETE \
'https://letoseo.com/api/v1/sites/:siteId/keywords' \
-H 'Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"ids": [
"00000000-0000-0000-0000-000000000021",
"00000000-0000-0000-0000-000000000022"
]
}'Path parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
siteId | uuid | required | The site UUID. | — |
Request body (application/json)
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
ids | uuid[] | required | Array of keyword target UUIDs to delete. Max 100. | — |
Example
{
"ids": [
"00000000-0000-0000-0000-000000000021",
"00000000-0000-0000-0000-000000000022"
]
}Responses
{
"error": "ids array is required"
}{
"error": "Site not found"
}