Digitalyser.io for developers
API referenceEditorial

Editorial topics for this project

Editorial topics, paginated.

Editorial topics, paginated. These are the source of the identifiers a content item is derived from — an integrator that creates content starts here.

Archived and rejected topics are hidden by default. includeArchived brings them back, and this matters: an archived topic is still derivable. Hidden is not the same as unusable.

GET/v1/projects/{projectId}/topics

Authorization

agent-token
AuthorizationBearer <token>

An agent project token. Obtained by OAuth consent for an AI client, or derived per project from an organisation service key for a machine. A scoped API key authenticates the transport but opens no capability: a capability takes its project from the credential.

In: header

Path Parameters

projectId*string

The project this call is about. A routing hint, not an authorisation. The project comes from the credential; this segment exists so multi-project code stays uniform. If it names a project outside the token, the call is refused with routing_hint_mismatch.

Formatuuid

Query Parameters

pageSize?integer

Items per page. Values above 50 are silently reduced to 50 — the response is not an error, it is simply shorter than asked. Read the returned length rather than assuming it.

Range1 <= value <= 50
Default20
page?integer

Page to read, 1-based.

Range1 <= value
Default1

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://app.digitalyser.io/api/v1/projects/550e8400-e29b-41d4-a716-446655440000/topics" \  -H "Authorization: Bearer <token>"
{  "coverage": {    "globalScore": 64,    "personaCoverage": {      "P1 restaurateur": 72,      "P2 artisan": 41    },    "intentCoverage": {      "informationnelle": 68,      "transactionnelle": 35    },    "pillarCoverage": {      "visibilité locale": 74,      "e-réputation": 52    },    "clusterCoverage": [      {        "cluster": "visibilité locale",        "score": 74      }    ],    "funnelCoverage": {      "TOFU": 71,      "MOFU": 46,      "BOFU": 22    }  },  "stats": {    "totalTopics": 47,    "totalPillars": 6,    "totalClusters": 11,    "totalIntents": 4,    "totalPersonas": 3,    "topicsByIntent": {      "informationnelle": 29,      "transactionnelle": 11,      "navigationnelle": 5,      "commerciale": 2    }  },  "items": [    {      "id": "6b1d8e35-4c70-4a92-8f16-2d9c7a0b5e48",      "projectId": "8f14e45f-ea0e-4b1e-9b7a-2c3d4e5f6071",      "title": "Why an incomplete Google listing costs calls",      "description": "How the three fields readers check before calling — hours, photos, answered reviews — decide whether a listing converts.",      "strategic_note": "Ranks for the queries the audit found unanswered, and the proof is already on hand.",      "marketing_goal": "Get a first audit request from a local business owner",      "target_problem": "People find me but never call",      "keywords": [        "fiche google incomplète",        "visibilité locale artisan"      ],      "intent": "informationnelle",      "persona": "P1 restaurateur",      "category": "actionable_advice",      "cluster": "visibilité locale",      "funnelStage": "TOFU",      "personaRelevance": {        "P1 restaurateur": 0.82,        "P2 artisan": 0.47      },      "recommendedFormats": [        "how_to",        "checklist"      ],      "recommendedCTA": "Check your own listing in two minutes",      "seoTitle": "Incomplete Google listing: the 3 fields that cost you calls",      "status": "approved",      "archivedAt": "2026-09-12T16:20:05.000Z",      "archiveReason": "Covered by a piece published in July; keeping both would split the same query.",      "createdAt": "2026-08-30T10:22:41.000Z",      "updatedAt": "2026-09-19T04:31:52.000Z"    }  ],  "total": 47,  "page": 1,  "pageSize": 20,  "limit": 20,  "hasNextPage": true,  "hasPreviousPage": false,  "totalPages": 3}

Generated from the capability registry — API version 1, 18 paths, from 4815355 (2026-10-12).

Was this page helpful?