Download OpenAPI specification:
The Enhancely API provides automatic generation and retrieval of Schema.org JSON-LD structured data for your web pages. This structured data helps search engines, AI platforms, and AI search tools better understand and represent your content.
1. Get Your API Key - Log in to the Enhancely Dashboard, add your domain, verify ownership, and copy your API key.
2. Make Your First Request - POST your page URL to /api/v1/jsonld with your API key. First request returns 201 (queued for processing). Wait a few minutes, then request again to get 200 with your generated JSON-LD.
3. Integrate Into Your Website - Add the returned JSON-LD in a <script type="application/ld+json"> tag in your page's <head> section. Implement caching with ETags for production.
This API is exclusively available to Enhancely customers who have:
Use POST /api/v1/jsonld for CMS & Website Integration:
412 Precondition Failed when ETag matches (cache valid)Use GET /api/v1/jsonld/{hash} for:
304 Not Modified when ETag matches (cache valid)Use GET /api/v1/jsonld for:
For integrating Enhancely into your website or CMS, follow this pattern:
<head> sectionIf-None-Match header with cached ETagpage.update:before). Auto-clear cache in local/development environments for testing.Note: Enhancely automatically checks all indexed URLs nightly. Normal content changes are detected via ETag validation on your next API call—manual cache clearing is only needed when you actively update content through your CMS.
Enhancely uses HTTP ETag-based caching:
Every JSON-LD response includes an ETag header—a unique identifier for that version of the content. Use ETags for efficient caching:
# First request
POST /api/v1/jsonld
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json
{"url": "https://example.com/page"}
HTTP/1.1 200 OK
ETag: "a1b2c3d4e5f6"
Content-Type: application/json
{
"hash": "7c165c13f93d7ca168bcfbd73cf563e3",
"url": "https://example.com/page",
"jsonld": {...},
"metadata": {},
"etag": "a1b2c3d4e5f6",
"crawled_at": "2025-01-16T14:30:00Z",
"status": "ready"
}
# Subsequent request with cached ETag
POST /api/v1/jsonld
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json
If-None-Match: "a1b2c3d4e5f6"
{"url": "https://example.com/page"}
HTTP/1.1 412 Precondition Failed
Benefits:
412 Precondition Failed responses include minimal Problem body indicating cache is validWhen HTML content changes, Enhancely reprocesses the JSON-LD and generates a new ETag.
If-None-Match header containing cached ETagJSON-LD generation is asynchronous. When you submit a URL:
Processing typically takes 1-3 minutes depending on page complexity and queue depth. The response includes a status field:
created: Queued for processing, JSON-LD generation hasn't started yet (typically returns 201 on first POST)updating: Currently being processed (returns 202 when still processing)ready: JSON-LD is available and ready to use (returns 200 with full content)failed: Generation failed (e.g., invalid page, unreachable URL)For newly created records or records being processed (201/202 responses), poll the GET /api/v1/jsonld/{hash} endpoint to check when processing completes and the status becomes ready.
All endpoints are rate-limited per domain. Each response includes rate limit headers to help you track your usage.
RateLimit-Limit: 100 # Maximum requests allowed in the current window
RateLimit-Remaining: 75 # Requests remaining in the current window
RateLimit-Reset: 1640000000 # Unix timestamp when the limit resets
429 Too Many Requests Response:
{
"type": "https://enhancely.ai/problems/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded your rate limit. Please try again later."
}
1. Monitor Rate Limit Headers
Check RateLimit-Remaining and RateLimit-Reset headers to track usage and implement proactive backoff when limits are approaching.
2. Implement Retry Logic
For 429 responses, wait until the RateLimit-Reset timestamp before retrying. For 5xx server errors, use exponential backoff (e.g., 1s, 2s, 4s).
3. Use Silent Degradation
When rate limited or encountering errors, return cached data or empty output rather than breaking page rendering.
The API uses standard HTTP status codes and RFC 7807 Problem Details format for errors.
Success States:
Cache States:
Client Errors (4xx):
Server Errors (5xx):
{
"type": "https://enhancely.ai/problems/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded your rate limit. Please try again later."
}
Endpoints for generating and retrieving Schema.org JSON-LD structured data from web page URLs.
These endpoints enable automatic creation of rich structured data that helps search engines, AI platforms, and AI search tools better understand and represent your content.
Retrieves a list of all JSON-LD records associated with your domain, providing an overview of indexed URLs and their processing status.
Primary use cases: Monitoring, troubleshooting, and auditing. For website integration, use the POST endpoint instead.
Filtering: Supports filtering by status, hash, etag, url, and timestamps (created_at, updated_at, crawled_at).
| etag | string Example: etag=a1b2c3d4e5f6 Filter by ETag value. Use |
| hash | string^[a-f0-9]{32}$ Example: hash=7c165c13f93d7ca168bcfbd73cf563e3 Filter by MD5 hash of the URL. See GET /api/v1/jsonld/{hash} endpoint for hash calculation details. |
| url | string <uri> Example: url=https://example.com/page Filter by the source URL. |
| id | string Filter by JSON-LD @id field. |
| status | string (JsonLdStatus) Enum: "created" "updating" "failed" "ready" Example: status=ready Filter by processing status. |
| created_at | string <date-time> Example: created_at=2025-01-01T00:00:00Z Filter records created after this timestamp. |
| updated_at | string <date-time> Example: updated_at=2025-01-01T00:00:00Z Filter records updated after this timestamp. |
| crawled_at | string <date-time> Example: crawled_at=2025-01-01T00:00:00Z Filter records crawled after this timestamp. |
[- {
- "hash": "7c165c13f93d7ca168bcfbd73cf563e3",
- "etag": "a1b2c3d4e5f6",
- "crawled_at": "2025-01-16T14:30:00Z",
- "status": "ready"
}, - {
- "hash": "9d8c7b6a5e4f3d2c1b0a9e8d7c6b5a4f",
- "etag": "f6e5d4c3b2a1",
- "crawled_at": "2025-01-16T15:00:00Z",
- "status": "ready"
}, - {
- "hash": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
- "etag": null,
- "crawled_at": null,
- "status": "created"
}
]Recommended endpoint for CMS plugins and website integrations.
Submits a URL for JSON-LD generation or retrieves existing data if already processed. Automatically creates new records if they don't exist.
Response Codes:
status: ready, updating, or failed)Key Features:
| If-None-Match | string Example: a1b2c3d4e5f6 Optional. The ETag value from a previous response. If provided and matches the current ETag, returns |
| Accept | string Enum: "application/json" "application/ld+json" Example: application/json Optional. Specify |
Required. JSON request body with the URL to generate JSON-LD for.
The Content-Type header must be application/json.
| url required | string <uri> The target page URL to generate JSON-LD for.
Example: |
{- "@graph": [
- {
- "@type": "WebPage",
- "name": "Lecture 12: Graphs, networks, incidence matrices",
- "description": "These video lectures of Professor Gilbert Strang teaching 18.06 were recorded in Fall 1999 and do not correspond precisely to the current edition of the textbook.",
- "publisher": {
- "@type": "CollegeOrUniversity",
- "name": "MIT OpenCourseWare"
},
}
]
}Retrieves JSON-LD for a URL using its MD5 hash. Primarily used for polling processing status after POST returns 201/202.
Primary use cases:
URL Hash Calculation:
The hash parameter is the MD5 hash of the absolute URL (lowercase hexadecimal):
import crypto from 'crypto';
const hash = crypto.createHash('md5').update('https://example.com/page').digest('hex');
// Result: "7c165c13f93d7ca168bcfbd73cf563e3"
Response Codes:
status field)If-None-Match header matches ETag)| hash required | string^[a-f0-9]{32}$ MD5 of the absolute URL (32 lowercase hexadecimal characters).
Example: |
| If-None-Match | string Example: a1b2c3d4e5f6 Optional. Return |
| Accept | string Enum: "application/json" "application/ld+json" Example: application/json Optional. Specify |
{- "@graph": [
- {
- "@type": "WebPage",
- "name": "Lecture 12: Graphs, networks, incidence matrices",
- "description": "These video lectures of Professor Gilbert Strang teaching 18.06 were recorded in Fall 1999 and do not correspond precisely to the current edition of the textbook.",
- "publisher": {
- "@type": "CollegeOrUniversity",
- "name": "MIT OpenCourseWare"
},
}
]
}