Indexhog - Search indexing and monitoring

Projects API

Indexing, monitoring, verification, and search-engine insights

2 min read

Website indexing and monitoring projects. Manage domain ownership, sitemap and URL inventory, IndexNow submissions, credit-funded URL inspections, daily statistics, and Google Search Console and Bing connections.

Available Endpoints

MethodEndpointDescription
GET/api/user/organizations/{organizationId}/projectsList organization projects
POST/api/user/organizations/{organizationId}/projectsCreate a new project
GET/api/user/organizations/{organizationId}/projects/{id}/activation-previewPreview scheduled inspection activation
PUT/api/user/organizations/{organizationId}/projects/{id}/automationConfigure scheduled inspections
GET/api/user/organizations/{organizationId}/projects/{id}Get a specific project
DELETE/api/user/organizations/{organizationId}/projects/{id}Delete a project
PATCH/api/user/organizations/{organizationId}/projects/{id}Update a project
PATCH/api/user/organizations/{organizationId}/projects/{id}/statusPause or resume a project
GET/api/user/organizations/{organizationId}/projects/{id}/urlsList tracked URLs for a project
POST/api/user/organizations/{organizationId}/projects/{id}/urlsManually admit URLs
GET/api/user/organizations/{organizationId}/projects/{id}/urls/{urlId}Get a tracked URL
GET/api/user/organizations/{organizationId}/projects/{id}/importsList URL import history
POST/api/user/organizations/{organizationId}/projects/{id}/importsUpload a CSV/txt URL list for preview
GET/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}Get import preview / progress
POST/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}/commitCommit a previewed import
GET/api/user/organizations/{organizationId}/projects/{id}/sitemapsList discovered sitemaps for a project
POST/api/user/organizations/{organizationId}/projects/{id}/syncManually sync project sitemaps
POST/api/user/organizations/{organizationId}/projects/{id}/availability/probeProbe robots / llms / sitemap availability
GET/api/user/organizations/{organizationId}/projects/{id}/verificationGet project verification status
POST/api/user/organizations/{organizationId}/projects/{id}/dns-tokenGenerate or rotate DNS verification token
POST/api/user/organizations/{organizationId}/projects/{id}/verify-dnsVerify DNS TXT ownership
POST/api/user/organizations/{organizationId}/projects/{id}/indexnow-keyGenerate or set IndexNow key
POST/api/user/organizations/{organizationId}/projects/{id}/verify-keyVerify IndexNow key file
GET/api/user/organizations/{organizationId}/projects/{id}/submissionsList IndexNow submission history
GET/api/user/organizations/{organizationId}/projects/{id}/issuesList issue groups for a project
GET/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}Get an issue group
PATCH/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}Update issue group status
GET/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}/urlsList memberships for an issue group
GET/api/user/organizations/{organizationId}/projects/{id}/statsGet live website stats
GET/api/user/organizations/{organizationId}/projects/{id}/snapshotsList daily website snapshots
GET/api/user/organizations/{organizationId}/projects/{id}/gsc/oauth-urlGet GSC OAuth authorize URL
POST/api/user/organizations/{organizationId}/projects/{id}/gsc/callbackComplete GSC OAuth and connect property
DELETE/api/user/organizations/{organizationId}/projects/{id}/gscDisconnect GSC
POST/api/user/organizations/{organizationId}/projects/{id}/bingConnect Bing Webmaster API key
DELETE/api/user/organizations/{organizationId}/projects/{id}/bingDisconnect Bing

Endpoints

GET/api/user/organizations/{organizationId}/projects

List organization projects

Get a paginated list of projects owned by the organization.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20
qstringSearch query

Response 200

Projects retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440001",
    "createdAt": "2024-01-01T00:00:00.000Z",
    "updatedAt": "2024-01-15T10:30:00.000Z",
    "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
    "name": "acme.com",
    "domain": "acme.com",
    "sitemapUrl": "https://acme.com/sitemap.xml",
    "status": "active",
    "inspectionCadence": "hourly",
    "automatedInspectionsEnabled": true,
    "verified": false,
    "indexNowKey": "a1b2c3d4e5f6",
    "indexNowKeySource": "generated",
    "indexNowKeyVerifiedAt": null,
    "dnsVerificationToken": null,
    "dnsVerifiedAt": null,
    "gscPropertyUrl": null,
    "gscConnectedAt": null,
    "bingConnectedAt": null,
    "robotsTxtPresent": null,
    "llmsTxtPresent": null,
    "lastAvailabilityCheckAt": null,
    "lastSitemapSyncAt": null,
    "lastEngineSyncAt": null
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects

Create a new project

Create an active project for a bare domain. Consumes a slot. Returns 409 on duplicate live domain.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"domain":"acme.com","name":"Acme Site","sitemapUrl":"https://acme.com/sitemap.xml"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
domainrequiredstringBare host (trim + lowercase). Immutable after create.
acme.com
namestringDisplay name; defaults to domain
Acme Site
sitemapUrlstringDefaults to https://{domain}/sitemap.xml
https://acme.com/sitemap.xml

Response 201

Project created successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/activation-preview

Preview scheduled inspection activation

Returns the current inventory and credits without consuming credits.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/activation-preview" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Activation preview fetched

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "verified": true,
  "trackedUrlCount": 0,
  "creditBalance": 0,
  "creditsForFullCycle": 0,
  "urlsInspectableNow": 0,
  "cadence": "hourly",
  "automatedInspectionsEnabled": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
PUT/api/user/organizations/{organizationId}/projects/{id}/automation

Configure scheduled inspections

Enabling requires verified ownership, at least one tracked URL, and available credits.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X PUT "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/automation" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"enabled":true,"cadence":"hourly"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
enabledrequiredboolean
cadencerequiredInspectionCadence

Response 200

Project automation updated

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}

Get a specific project

Get details of a specific project owned by the organization.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Project retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
DELETE/api/user/organizations/{organizationId}/projects/{id}

Delete a project

Soft delete a project (paused + deletedAt). Idempotent.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X DELETE "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Project deleted successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
PATCH/api/user/organizations/{organizationId}/projects/{id}

Update a project

Update name and/or sitemapUrl. Domain is immutable.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X PATCH "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"name":"Acme Site","sitemapUrl":"https://acme.com/sitemap.xml"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
namestringProject display name
Acme Site
sitemapUrlstringSitemap URL (domain is immutable)
https://acme.com/sitemap.xml

Response 200

Project updated successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
PATCH/api/user/organizations/{organizationId}/projects/{id}/status

Pause or resume a project

Set status to active or paused. Pausing does not free workspace capacity.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X PATCH "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/status" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"status":"paused"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
statusrequiredProjectStatus

Response 200

Project status updated successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440001",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z",
  "createdByUserId": "550e8400-e29b-41d4-a716-446655440002",
  "name": "acme.com",
  "domain": "acme.com",
  "sitemapUrl": "https://acme.com/sitemap.xml",
  "status": "active",
  "inspectionCadence": "hourly",
  "automatedInspectionsEnabled": true,
  "verified": false,
  "indexNowKey": "a1b2c3d4e5f6",
  "indexNowKeySource": "generated",
  "indexNowKeyVerifiedAt": null,
  "dnsVerificationToken": null,
  "dnsVerifiedAt": null,
  "gscPropertyUrl": null,
  "gscConnectedAt": null,
  "bingConnectedAt": null,
  "robotsTxtPresent": null,
  "llmsTxtPresent": null,
  "lastAvailabilityCheckAt": null,
  "lastSitemapSyncAt": null,
  "lastEngineSyncAt": null
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/urls

List tracked URLs for a project

Paginated inventory with optional health/indexability/engine/source/stale filters.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/urls" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20
healthStateHealthStateFilter by health state
indexabilityIndexabilityFilter by indexability
googleStateGoogleStateFilter by Google state
bingStateBingStateFilter by Bing state
sourceUrlSourceFilter by discovery source
hasIssuesstringFilter URLs that currently belong to an open issue group
isStalestringFilter URLs with staleAt set (missing from sitemap)
disagreementDisagreementFilter audit-vs-engine disagreements without collapsing facts. indexable_not_in_engine = our audit indexable + Google/Bing non-indexed; nonindexable_but_indexed = our audit non-indexable + an engine reports indexed; any = either.

Response 200

Tracked URLs retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://acme.com/about",
    "source": "sitemap",
    "discoveredAt": "string",
    "firstSeenInSitemapAt": "string",
    "lastSeenInSitemapAt": "string",
    "lastmod": "string",
    "staleAt": "string",
    "healthState": "unknown",
    "httpStatus": 0,
    "redirectTarget": "string",
    "redirectHops": 0,
    "healthError": "string",
    "lastHealthCheckAt": "string",
    "indexability": "unknown",
    "canonicalUrl": "string",
    "metaRobots": "string",
    "xRobotsTag": "string",
    "lastAuditAt": "string",
    "lastInspectionAttemptAt": "string",
    "lastInspectionSuccessAt": "string",
    "lastInspectionFailureAt": "string",
    "lastInspectionFailureCode": "string",
    "consecutiveInspectionFailures": 0,
    "lastIndexNowSubmittedAt": "string",
    "indexNowAttempts": 0,
    "googleState": "unknown",
    "bingState": "unknown",
    "indexedAt": "string",
    "lastEngineSyncAt": "string",
    "nextInspectionAt": "string",
    "createdAt": "string",
    "updatedAt": "string"
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/urls

Manually admit URLs

Normalize, same-host filter, dedup, and insert without consuming credits. One invalid URL rejects the batch (400).

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/urls" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"urls":["https://acme.com/about","https://acme.com/pricing"]}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
urlsrequiredstring[]Raw URLs to admit (1–1000). Normalized before dedup.
https://acme.com/about,https://acme.com/pricing

Response 200

URLs admitted successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "inserted": 3,
  "skipped": 2,
  "skippedOffHost": [
    {
      "url": "https://other.com/page",
      "reason": "off_host"
    }
  ]
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/urls/{urlId}

Get a tracked URL

Detail for one live tracked URL in the project.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/urls/{urlId}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
urlIdrequiredstringTracked URL ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Tracked URL retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://acme.com/about",
  "source": "sitemap",
  "discoveredAt": "string",
  "firstSeenInSitemapAt": "string",
  "lastSeenInSitemapAt": "string",
  "lastmod": "string",
  "staleAt": "string",
  "healthState": "unknown",
  "httpStatus": 0,
  "redirectTarget": "string",
  "redirectHops": 0,
  "healthError": "string",
  "lastHealthCheckAt": "string",
  "indexability": "unknown",
  "canonicalUrl": "string",
  "metaRobots": "string",
  "xRobotsTag": "string",
  "lastAuditAt": "string",
  "lastInspectionAttemptAt": "string",
  "lastInspectionSuccessAt": "string",
  "lastInspectionFailureAt": "string",
  "lastInspectionFailureCode": "string",
  "consecutiveInspectionFailures": 0,
  "lastIndexNowSubmittedAt": "string",
  "indexNowAttempts": 0,
  "googleState": "unknown",
  "bingState": "unknown",
  "indexedAt": "string",
  "lastEngineSyncAt": "string",
  "nextInspectionAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/imports

List URL import history

Paginated import previews and commits for a project.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/imports" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20

Response 200

Imports retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "pending",
    "fileName": "urls.csv",
    "fileSizeBytes": 0,
    "contentSha256": "string",
    "headerDetected": true,
    "totalRows": 0,
    "validRows": 0,
    "invalidRows": 0,
    "duplicateInFileRows": 0,
    "alreadyTrackedRows": 0,
    "netNewRows": 0,
    "rowErrors": [
      {
        "line": 12,
        "reason": "URL is malformed",
        "value": "not-a-url"
      }
    ],
    "processedRows": 0,
    "insertedRows": 0,
    "skippedRows": 0,
    "error": "string",
    "expiresAt": "string",
    "committedAt": "string",
    "completedAt": "string",
    "createdAt": "string",
    "updatedAt": "string"
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/imports

Upload a CSV/txt URL list for preview

Stores the file and builds a preview only — zero tracked-URL writes and zero credit debit. Limits: 50,000 rows / 5 MiB. CSV first column; plain text one URL per line; optional header auto-detected.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/imports" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 201

Import preview created

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "fileName": "urls.csv",
  "fileSizeBytes": 0,
  "contentSha256": "string",
  "headerDetected": true,
  "totalRows": 0,
  "validRows": 0,
  "invalidRows": 0,
  "duplicateInFileRows": 0,
  "alreadyTrackedRows": 0,
  "netNewRows": 0,
  "rowErrors": [
    {
      "line": 12,
      "reason": "URL is malformed",
      "value": "not-a-url"
    }
  ],
  "processedRows": 0,
  "insertedRows": 0,
  "skippedRows": 0,
  "error": "string",
  "expiresAt": "string",
  "committedAt": "string",
  "completedAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}

Get import preview / progress

Preview totals, per-row errors, and commit progress/failure.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
importIdrequiredstringURL import ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Import retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "fileName": "urls.csv",
  "fileSizeBytes": 0,
  "contentSha256": "string",
  "headerDetected": true,
  "totalRows": 0,
  "validRows": 0,
  "invalidRows": 0,
  "duplicateInFileRows": 0,
  "alreadyTrackedRows": 0,
  "netNewRows": 0,
  "rowErrors": [
    {
      "line": 12,
      "reason": "URL is malformed",
      "value": "not-a-url"
    }
  ],
  "processedRows": 0,
  "insertedRows": 0,
  "skippedRows": 0,
  "error": "string",
  "expiresAt": "string",
  "committedAt": "string",
  "completedAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}/commit

Commit a previewed import

Requires explicit confirm:true. Rechecks net-new rows, then enqueues a background commit chunked at 1,000. Importing URLs does not consume credits. Expired/stale preview → 409.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/imports/{importId}/commit" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"confirm":true}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
importIdrequiredstringURL import ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
confirmrequiredbooleanExplicit consent to import the valid rows from this preview
true

Response 200

Import commit accepted

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "fileName": "urls.csv",
  "fileSizeBytes": 0,
  "contentSha256": "string",
  "headerDetected": true,
  "totalRows": 0,
  "validRows": 0,
  "invalidRows": 0,
  "duplicateInFileRows": 0,
  "alreadyTrackedRows": 0,
  "netNewRows": 0,
  "rowErrors": [
    {
      "line": 12,
      "reason": "URL is malformed",
      "value": "not-a-url"
    }
  ],
  "processedRows": 0,
  "insertedRows": 0,
  "skippedRows": 0,
  "error": "string",
  "expiresAt": "string",
  "committedAt": "string",
  "completedAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/sitemaps

List discovered sitemaps for a project

Returns sitemap documents recorded for the project (root, robots-declared, and children).

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/sitemaps" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Sitemaps retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://acme.com/sitemap.xml",
    "type": "index",
    "parentSitemapId": "550e8400-e29b-41d4-a716-446655440000",
    "lastFetchedAt": "string",
    "lastSuccessAt": "string",
    "fetchStatus": "ok",
    "urlCount": 0,
    "error": "string"
  }
]
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/sync

Manually sync project sitemaps

Walks sitemap roots, admits on-host URLs (1 credit each), marks stale. 15-minute debounce → 429. Insufficient credits → 402.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/sync" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Sitemap sync completed

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "urlsDiscovered": 0,
  "urlsUpdated": 0,
  "urlsSkipped": 0,
  "sitemapsFetched": 0,
  "staleMarked": 0,
  "staleCleared": 0,
  "skippedOffHost": [
    {
      "url": "https://other.com/page",
      "reason": "off_host"
    }
  ]
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/availability/probe

Probe robots / llms / sitemap availability

Runs the P5 availability probe and updates project presence flags. Ungated — runs before verification.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/availability/probe" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Availability probed successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "robotsTxtPresent": true,
  "llmsTxtPresent": true,
  "sitemapPresent": true,
  "robotsSitemapUrls": [
    "string"
  ]
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/verification

Get project verification status

Returns DNS / IndexNow / GSC / Bing verification projection. Token and key are shown for setup; they are not credentials.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/verification" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Verification status retrieved

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "verified": true,
  "dnsRecordName": "_indexhog.acme.com",
  "dnsRecordValue": "indexhog-site-verification=abc…",
  "dnsVerificationToken": "string",
  "dnsVerifiedAt": "string",
  "indexNowKey": "string",
  "indexNowKeySource": "generated",
  "indexNowKeyFileUrl": "https://acme.com/{key}.txt",
  "indexNowKeyVerifiedAt": "string",
  "gscConnectedAt": "string",
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/dns-token

Generate or rotate DNS verification token

Creates a new 64-hex DNS token and clears dnsVerifiedAt. Publish as TXT at `_indexhog.{domain}` with value `indexhog-site-verification={token}`.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/dns-token" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

DNS token rotated

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "verified": true,
  "dnsRecordName": "_indexhog.acme.com",
  "dnsRecordValue": "indexhog-site-verification=abc…",
  "dnsVerificationToken": "string",
  "dnsVerifiedAt": "string",
  "indexNowKey": "string",
  "indexNowKeySource": "generated",
  "indexNowKeyFileUrl": "https://acme.com/{key}.txt",
  "indexNowKeyVerifiedAt": "string",
  "gscConnectedAt": "string",
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/verify-dns

Verify DNS TXT ownership

Resolves `_indexhog.{domain}` TXT live (no negative cache) and exact-matches after trim.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/verify-dns" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

DNS verification attempted

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "verified": true,
  "error": "string",
  "verification": {
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "acme.com",
    "verified": true,
    "dnsRecordName": "_indexhog.acme.com",
    "dnsRecordValue": "indexhog-site-verification=abc…",
    "dnsVerificationToken": "string",
    "dnsVerifiedAt": "string",
    "indexNowKey": "string",
    "indexNowKeySource": "generated",
    "indexNowKeyFileUrl": "https://acme.com/{key}.txt",
    "indexNowKeyVerifiedAt": "string",
    "gscConnectedAt": "string",
    "bingConnectedAt": "string"
  }
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/indexnow-key

Generate or set IndexNow key

Empty body generates a 64-hex key; `{key}` provides 8–128 `[a-zA-Z0-9-]`. Clears indexNowKeyVerifiedAt.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/indexnow-key" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"key":"my-indexnow-key-01"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
keystringOmit or empty to generate a 64-hex key; otherwise provide 8–128 chars [a-zA-Z0-9-]
my-indexnow-key-01

Response 200

IndexNow key set

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "verified": true,
  "dnsRecordName": "_indexhog.acme.com",
  "dnsRecordValue": "indexhog-site-verification=abc…",
  "dnsVerificationToken": "string",
  "dnsVerifiedAt": "string",
  "indexNowKey": "string",
  "indexNowKeySource": "generated",
  "indexNowKeyFileUrl": "https://acme.com/{key}.txt",
  "indexNowKeyVerifiedAt": "string",
  "gscConnectedAt": "string",
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/verify-key

Verify IndexNow key file

Fetches `https://{domain}/{key}.txt` (SSRF-safe) and exact-matches the body after trim.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/verify-key" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Key verification attempted

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "verified": true,
  "error": "string",
  "verification": {
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "acme.com",
    "verified": true,
    "dnsRecordName": "_indexhog.acme.com",
    "dnsRecordValue": "indexhog-site-verification=abc…",
    "dnsVerificationToken": "string",
    "dnsVerifiedAt": "string",
    "indexNowKey": "string",
    "indexNowKeySource": "generated",
    "indexNowKeyFileUrl": "https://acme.com/{key}.txt",
    "indexNowKeyVerifiedAt": "string",
    "gscConnectedAt": "string",
    "bingConnectedAt": "string"
  }
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/submissions

List IndexNow submission history

Append-only IndexNow batch history for the project, newest first. Automatic submissions only — there is no manual submit endpoint. Batch summaries are retained forever; per-URL submission detail joins are retained for 90 days.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/submissions" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20

Response 200

Submissions retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "engine": "indexnow",
    "urlCount": 0,
    "status": "pending",
    "responseCode": 0,
    "responseBody": "string",
    "error": "string",
    "createdAt": "string"
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/issues

List issue groups for a project

Paginated (project, type) issue groups. Ordered severity DESC, affectedUrlCount DESC. Filters: type, severity, status.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/issues" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20
typeIssueTypeFilter by issue type
severityIssueSeverityFilter by severity
statusIssueStatusFilter by status

Response 200

Issues retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "type": "broken_link",
    "severity": "critical",
    "status": "open",
    "affectedUrlCount": 412,
    "sampleUrls": [
      "string"
    ],
    "firstDetectedAt": "string",
    "lastDetectedAt": "string",
    "resolvedAt": "string",
    "metadata": {},
    "createdAt": "string",
    "updatedAt": "string"
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}

Get an issue group

Detail for one (project, type) issue group.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
issueIdrequiredstringIssue group ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Issue retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "type": "broken_link",
  "severity": "critical",
  "status": "open",
  "affectedUrlCount": 412,
  "sampleUrls": [
    "string"
  ],
  "firstDetectedAt": "string",
  "lastDetectedAt": "string",
  "resolvedAt": "string",
  "metadata": {},
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
PATCH/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}

Update issue group status

Manual status transition. ignored silences the whole type for the project (does not set resolvedAt). open reopens. resolved emits issue.resolved.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X PATCH "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"status":"open"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
issueIdrequiredstringIssue group ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
statusrequiredIssueStatus

Response 200

Issue status updated successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "type": "broken_link",
  "severity": "critical",
  "status": "open",
  "affectedUrlCount": 412,
  "sampleUrls": [
    "string"
  ],
  "firstDetectedAt": "string",
  "lastDetectedAt": "string",
  "resolvedAt": "string",
  "metadata": {},
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}/urls

List memberships for an issue group

Paginated drill-down into issue_urls membership. Open memberships (resolvedAt null) first.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/issues/{issueId}/urls" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000
issueIdrequiredstringIssue group ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
offsetnumber | nullNumber of items to skip
0
limitnumberNumber of items to return (max 100)
20

Response 200

Issue memberships retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Items fetched successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "issueId": "550e8400-e29b-41d4-a716-446655440000",
    "trackedUrlId": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://acme.com/about",
    "detectedAt": "string",
    "resolvedAt": "string",
    "createdAt": "string",
    "updatedAt": "string"
  }
],
"meta": {
  "total": 100,
  "offset": 0,
  "limit": 10,
  "hasMore": true
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/stats

Get live website stats

Nine raw counters for the project. Returns zeros when no stats row exists. Ratios are not stored — compute client-side.

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/stats" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Stats retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "totalUrls": 0,
  "healthyUrls": 0,
  "brokenUrls": 0,
  "redirectedUrls": 0,
  "indexedUrls": 0,
  "notIndexedUrls": 0,
  "staleUrls": 0,
  "openIssues": 0,
  "urlsWithIssues": 0,
  "lastReconciledAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/snapshots

List daily website snapshots

Immutable daily snapshots ascending by date. Window clamped to 1–365 days (default 30).

Bearer Token•Scopes: projects:read, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/snapshots" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
daysnumberSnapshot window in days (1–365)
30

Response 200

Snapshots retrieved successfully

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "date": "2026-07-29",
    "totalUrls": 0,
    "healthyUrls": 0,
    "brokenUrls": 0,
    "redirectedUrls": 0,
    "indexedUrls": 0,
    "notIndexedUrls": 0,
    "staleUrls": 0,
    "openIssues": 0,
    "urlsWithIssues": 0,
    "createdAt": "string"
  }
]
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
GET/api/user/organizations/{organizationId}/projects/{id}/gsc/oauth-url

Get GSC OAuth authorize URL

Returns Google authorize URL with access_type=offline and prompt=consent. CSRF state is stored server-side. Requires GSC_OAUTH_* Infisical keys.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X GET "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/gsc/oauth-url" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Query Parameters

NameTypeDescription
statestringOptional client-supplied CSRF state (≥16 chars). When omitted, the server generates one.

Response 200

OAuth URL generated

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "authorizeUrl": "https://accounts.google.com/o/oauth2/v2/auth",
  "state": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/gsc/callback

Complete GSC OAuth and connect property

Exchanges code for refresh token, validates property against sites.list and domain coverage, encrypts refresh token at rest. Stamps gscConnectedAt (verification signal). Never returns secrets.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/gsc/callback" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"code":"string","state":"string","propertyUrl":"sc-domain:acme.com"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
coderequiredstringOAuth authorization code
staterequiredstringCSRF state from oauth-url
propertyUrlrequiredstringGSC property URL verbatim (sc-domain:… or https://…/); must cover project domain
sc-domain:acme.com

Response 200

GSC connected

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "gscConnected": true,
  "gscConnectedAt": "string",
  "gscPropertyUrl": "string",
  "bingConnected": true,
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
DELETE/api/user/organizations/{organizationId}/projects/{id}/gsc

Disconnect GSC

Clears encrypted refresh token, property URL, and gscConnectedAt. Preserves historical googleState on tracked URLs.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X DELETE "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/gsc" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

GSC disconnected

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "gscConnected": true,
  "gscConnectedAt": "string",
  "gscPropertyUrl": "string",
  "bingConnected": true,
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
POST/api/user/organizations/{organizationId}/projects/{id}/bing

Connect Bing Webmaster API key

Validates key length (≥16), pings Bing GetUrlInfo, encrypts key at rest, stamps bingConnectedAt. Never returns the key.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X POST "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/bing" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"apiKey":"string"}'

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Body Parameters

NameTypeDescription
apiKeyrequiredstringBing Webmaster Tools API key (≥16 characters)

Response 200

Bing connected

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "gscConnected": true,
  "gscConnectedAt": "string",
  "gscPropertyUrl": "string",
  "bingConnected": true,
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}
DELETE/api/user/organizations/{organizationId}/projects/{id}/bing

Disconnect Bing

Clears encrypted API key and bingConnectedAt. Preserves historical bingState on tracked URLs.

Bearer Token•Scopes: projects:write, organization:read

Request

curl -X DELETE "https://api.indexhog.com/api/user/organizations/{organizationId}/projects/{id}/bing" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json"

Path Parameters

NameTypeDescription
organizationIdrequiredstringOrganization ID
550e8400-e29b-41d4-a716-446655440000
idrequiredstringProject ID
550e8400-e29b-41d4-a716-446655440000

Response 200

Bing disconnected

{
"success": true,
"status": 200,
"code": "OK",
"message": "Operation completed successfully",
"data": {
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "domain": "acme.com",
  "gscConnected": true,
  "gscConnectedAt": "string",
  "gscPropertyUrl": "string",
  "bingConnected": true,
  "bingConnectedAt": "string"
}
}

Error Responses

401— Unauthorized - Invalid or missing authentication

{
"success": false,
"status": 401,
"code": "UNAUTHORIZED",
"message": "Authentication required"
}

403— Forbidden - Insufficient permissions

{
"success": false,
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have permission to perform this action"
}