AUTHENTICATION
Use your Workspace API key.
Send the one-time-revealed oslr_ key in X-API-Key. Never place the key in a URL, browser script, public repository, or support message.
AI READER API GUIDE
Read or summarize public HTTPS content synchronously, or submit Direct async jobs and receive signed completion webhooks. Build reliable inputs for LLM, RAG, and agent workflows.
AUTHENTICATION
Send the one-time-revealed oslr_ key in X-API-Key. Never place the key in a URL, browser script, public repository, or support message.
CREDIT USAGE
Reader and Document use 1 credit on success; Summary uses 5. Async jobs reserve the same amount at submission and settle it only after the terminal result is reconciled. Partial results, failures, cancellations, and Gateway rejections use 0 credits.
REQUEST TRACKING
X-Request-IdDirect responses include an opaque X-Request-Id after request preparation. Include it in a support request about that operation. Early authentication or ingress rejection may not have one.
POST RETRIES
Idempotency-Key lets the Gateway recognize the same logical POST operation when a network timeout or client interruption leaves its result uncertain. It is optional for synchronous POST endpoints and required for every async submission.
Idempotency-Key Replace the value shown in each POST example with a newly generated value. Do not reuse the example value for a real request.
QUICK START
Use an OngsooLabs-authored static HTML input to quickly inspect the Direct API request and response shape without making a live API call.
POST /api/v1/readerX-API-Key: oslr_your_api_keymarkdownPOST /api/v1/reader
X-API-Key: oslr_your_api_key
Idempotency-Key: <new UUID or ULID for this POST>
Content-Type: application/json
{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-source.html",
"mode": "generic",
"output_format": "markdown",
"enable_chunking": false
}
X-Request-Id: dgr_example_request_id
{
"status": "success",
"title": "OngsooLabs controlled Reader source",
"content": {
"format": "markdown",
"value": "# OngsooLabs controlled Reader source\n\nThis page is an owned, controlled input..."
},
"usage": { "credits": 1 }
}
The source page and the sanitized contract example are maintained by OngsooLabs.
OngsooLabs Direct is publicly available. Sign in to create a Direct API key and manage credits and billing in the Dashboard. This static example does not execute an API call.
/api/v1/reader
Extract clean main content, metadata, and optional chunks from one public HTTPS webpage using URL query parameters.
Use it when: you need a simple URL-based integration, agent tool, or quick diagnostic request without a JSON body.
https://ongsoolabs.com| Parameter | Requirement | Default | Description |
|---|---|---|---|
url |
Required | - |
Public HTTPS webpage URL. |
output_format |
Optional | markdown |
markdown, text, or json output. |
tokenizer |
Optional | openai |
Tokenizer estimate: openai, claude, gemini, or llama. |
enable_chunking |
Optional | false |
Include overlapping chunks in a Reader or Document response. |
chunk_size_tokens |
Optional | 500 |
Target token count for each token-based chunk. |
overlap_size_tokens |
Optional | 100 |
Token overlap between adjacent chunks; must be smaller than chunk size. |
force_dynamic |
Optional | false |
Request browser rendering for a page that requires client-side rendering; it does not bypass access controls. |
mode |
Optional | generic |
Extraction mode: generic, article, documentation, product, or forum. |
output_content |
Optional | true |
Controls content, metadata, tables, code blocks, images, and links in the response. |
output_metadata |
Optional | true |
Controls content, metadata, tables, code blocks, images, and links in the response. |
output_tables |
Optional | true |
Controls content, metadata, tables, code blocks, images, and links in the response. |
output_code_blocks |
Optional | true |
Controls content, metadata, tables, code blocks, images, and links in the response. |
output_images |
Optional | false |
Controls content, metadata, tables, code blocks, images, and links in the response. |
output_links |
Optional | false |
Controls content, metadata, tables, code blocks, images, and links in the response. |
disable_css |
Optional | null |
Optional rendering hint. Leave unset unless validating a known rendering issue. |
curl --request GET \
--url "https://ongsoolabs.com/api/v1/reader?url=https%3A%2F%2Fongsoolabs.com%2Fexamples%2Freader%2Fowned-controlled-reader-source.html&output_format=markdown&mode=article" \
--header "X-API-Key: oslr_your_api_key"$headers = @{
"X-API-Key" = "oslr_your_api_key"
}
Invoke-RestMethod -Method GET `
-Uri "https://ongsoolabs.com/api/v1/reader?url=https%3A%2F%2Fongsoolabs.com%2Fexamples%2Freader%2Fowned-controlled-reader-source.html&output_format=markdown&mode=article" `
-Headers $headers{
"id": "read_example",
"status": "success",
"contentType": "webpage",
"title": "OngsooLabs Reader controlled source",
"content": {
"format": "markdown",
"value": "# Controlled Reader source\n\nThis page is maintained by OngsooLabs for Reader contract verification."
},
"usage": {
"characters": 92,
"tokens": 18,
"chunks": 0,
"credits": 1
}
}{
"id": "read_example",
"status": "partial",
"error": {
"code": "PARTIAL_CONTENT",
"message": "The extracted main content did not meet the quality gate.",
"retryable": true,
"recommendedProfile": "standard"
},
"usage": {
"characters": 0,
"tokens": 0,
"chunks": 0,
"credits": 0
}
}This example is based on the approved API specification.
/api/v1/reader
Extract clean Markdown, text, or structured JSON from one public HTTPS webpage with explicit output and chunking controls.
Use it when: you need reproducible RAG ingestion, metadata controls, dynamic-render fallback, or optional inline chunking.
https://ongsoolabs.com| Parameter | Requirement | Default | Description |
|---|---|---|---|
url |
Required | - |
Public HTTPS webpage URL. |
output_format |
Optional | markdown |
markdown, text, or json output. |
tokenizer |
Optional | openai |
Tokenizer estimate: openai, claude, gemini, or llama. |
enable_chunking |
Optional | false |
Include overlapping chunks in a Reader or Document response. |
chunk_size_tokens |
Optional | 500 |
Target token count for each token-based chunk. |
overlap_size_tokens |
Optional | 100 |
Token overlap between adjacent chunks; must be smaller than chunk size. |
force_dynamic |
Optional | false |
Request browser rendering for a page that requires client-side rendering; it does not bypass access controls. |
mode |
Optional | generic |
Extraction mode: generic, article, documentation, product, or forum. |
output |
Optional | object defaults |
Controls content, metadata, tables, code blocks, images, and links in the response. |
disable_css |
Optional | null |
Optional rendering hint. Leave unset unless validating a known rendering issue. |
curl --request POST \
--url "https://ongsoolabs.com/api/v1/reader" \
--header "X-API-Key: oslr_your_api_key" \
--header "Idempotency-Key: 00000000-0000-4000-8000-000000000000" \
--header "Content-Type: application/json" \
--data '{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-source.html",
"output_format": "markdown",
"tokenizer": "openai",
"enable_chunking": false,
"force_dynamic": false,
"mode": "article"
}'$headers = @{
"X-API-Key" = "oslr_your_api_key"
"Idempotency-Key" = "00000000-0000-4000-8000-000000000000"
}
$body = @'
{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-source.html",
"output_format": "markdown",
"tokenizer": "openai",
"enable_chunking": false,
"force_dynamic": false,
"mode": "article"
}
'@
Invoke-RestMethod -Method POST `
-Uri "https://ongsoolabs.com/api/v1/reader" `
-Headers $headers `
-ContentType "application/json" `
-Body $body{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-source.html",
"output_format": "markdown",
"tokenizer": "openai",
"enable_chunking": false,
"force_dynamic": false,
"mode": "article"
}{
"id": "read_example",
"status": "success",
"contentType": "webpage",
"title": "OngsooLabs Reader controlled source",
"content": {
"format": "markdown",
"value": "# Controlled Reader source\n\nThis page is maintained by OngsooLabs for Reader contract verification."
},
"usage": {
"characters": 92,
"tokens": 18,
"chunks": 0,
"credits": 1
}
}{
"id": "read_example",
"status": "failed",
"error": {
"code": "INVALID_REQUEST",
"message": "The request options are invalid.",
"retryable": false
},
"usage": {
"characters": 0,
"tokens": 0,
"chunks": 0,
"credits": 0
}
}This example is based on the approved API specification.
/api/v1/reader/document
Convert a public HTTPS text-layer PDF URL to Markdown with optional token counting and chunking.
Use it when: you need text from a public specification, report, or paper that already contains an extractable text layer.
https://ongsoolabs.com| Parameter | Requirement | Default | Description |
|---|---|---|---|
url |
Required | - |
Public HTTPS URL for a PDF with an extractable text layer. |
tokenizer |
Optional | openai |
Tokenizer estimate: openai, claude, gemini, or llama. |
enable_chunking |
Optional | false |
Include overlapping chunks in a Reader or Document response. |
chunk_size_tokens |
Optional | 500 |
Target token count for each token-based chunk. |
overlap_size_tokens |
Optional | 100 |
Token overlap between adjacent chunks; must be smaller than chunk size. |
curl --request POST \
--url "https://ongsoolabs.com/api/v1/reader/document" \
--header "X-API-Key: oslr_your_api_key" \
--header "Idempotency-Key: 00000000-0000-4000-8000-000000000000" \
--header "Content-Type: application/json" \
--data '{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-document.pdf",
"tokenizer": "openai",
"enable_chunking": false
}'$headers = @{
"X-API-Key" = "oslr_your_api_key"
"Idempotency-Key" = "00000000-0000-4000-8000-000000000000"
}
$body = @'
{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-document.pdf",
"tokenizer": "openai",
"enable_chunking": false
}
'@
Invoke-RestMethod -Method POST `
-Uri "https://ongsoolabs.com/api/v1/reader/document" `
-Headers $headers `
-ContentType "application/json" `
-Body $body{
"url": "https://ongsoolabs.com/examples/reader/owned-controlled-reader-document.pdf",
"tokenizer": "openai",
"enable_chunking": false
}{
"id": "read_document_example",
"status": "success",
"contentType": "document",
"title": "OngsooLabs Reader controlled document",
"content": {
"format": "markdown",
"value": "# OngsooLabs Reader controlled document\n\nThis text-layer PDF is maintained for Reader contract verification."
},
"usage": {
"characters": 105,
"tokens": 19,
"chunks": 0,
"credits": 1
},
"execution": {
"profile": "document",
"usedBrowser": false
}
}{
"id": "read_document_example",
"status": "failed",
"error": {
"code": "DOCUMENT_NO_TEXT_LAYER",
"message": "The PDF does not contain extractable text.",
"retryable": false
},
"usage": {
"characters": 0,
"tokens": 0,
"chunks": 0,
"credits": 0
},
"execution": {
"profile": "document",
"usedBrowser": false
}
}This example is based on the approved API specification.
/api/v1/reader/chunk
Split supplied text into ordered overlapping token- or character-based chunks for embedding and retrieval pipelines.
Use it when: you already have source text and need deterministic chunk boundaries without fetching a URL.
https://ongsoolabs.com| Parameter | Requirement | Default | Description |
|---|---|---|---|
text |
Required | - |
Raw text to split; maximum 1,000,000 characters. |
tokenizer |
Optional | openai |
Tokenizer estimate: openai, claude, gemini, or llama. |
use_tokens |
Optional | true |
Use token-based chunk sizes when true; character sizes when false. |
chunk_size_tokens |
Optional | 500 |
Target token count for each token-based chunk. |
overlap_size_tokens |
Optional | 100 |
Token overlap between adjacent chunks; must be smaller than chunk size. |
chunk_size |
Optional | 1000 |
Target character count when use_tokens is false. |
overlap_size |
Optional | 200 |
Character overlap when use_tokens is false; must be smaller than chunk size. |
curl --request POST \
--url "https://ongsoolabs.com/api/v1/reader/chunk" \
--header "X-API-Key: oslr_your_api_key" \
--header "Idempotency-Key: 00000000-0000-4000-8000-000000000000" \
--header "Content-Type: application/json" \
--data '{
"text": "OngsooLabs Reader prepares clean source text for retrieval pipelines. This controlled sample demonstrates overlapping token chunks.",
"tokenizer": "openai",
"use_tokens": true,
"chunk_size_tokens": 32,
"overlap_size_tokens": 8
}'$headers = @{
"X-API-Key" = "oslr_your_api_key"
"Idempotency-Key" = "00000000-0000-4000-8000-000000000000"
}
$body = @'
{
"text": "OngsooLabs Reader prepares clean source text for retrieval pipelines. This controlled sample demonstrates overlapping token chunks.",
"tokenizer": "openai",
"use_tokens": true,
"chunk_size_tokens": 32,
"overlap_size_tokens": 8
}
'@
Invoke-RestMethod -Method POST `
-Uri "https://ongsoolabs.com/api/v1/reader/chunk" `
-Headers $headers `
-ContentType "application/json" `
-Body $body{
"text": "OngsooLabs Reader prepares clean source text for retrieval pipelines. This controlled sample demonstrates overlapping token chunks.",
"tokenizer": "openai",
"use_tokens": true,
"chunk_size_tokens": 32,
"overlap_size_tokens": 8
}[
{
"index": 0,
"start_char": 0,
"end_char": 120,
"token_count": 24,
"content": "OngsooLabs Reader prepares clean source text for retrieval pipelines. This controlled sample demonstrates overlapping token chunks."
}
]{
"id": "read_chunk_example",
"status": "failed",
"error": {
"code": "INVALID_REQUEST",
"message": "Chunk size or overlap is outside the supported boundary.",
"retryable": false
},
"usage": {
"characters": 0,
"tokens": 0,
"chunks": 0,
"credits": 0
}
}This example is based on the approved API specification.
/api/v1/summarySubmit one public HTTPS webpage URL. quality is optional and currently accepts standard.
https://ongsoolabs.com{
"url": "https://example.com/article",
"quality": "standard"
}Idempotency-Key Use a unique UUID D-format or ULID for each logical POST operation, and reuse it only when retrying that same operation. Reusing it with a different request returns 409.
A successful response contains a versioned Summary object with title, summary, best-effort keywords, sourceType, usage, and execution. Provider and model names are not exposed.
POST /api/v1/{operation}/jobsSubmit work without keeping the original HTTP connection open. A successful submission returns 202 Accepted with an opaque job ID and URLs for status and result retrieval.
Use it when: the caller can poll for completion or receive a completion webhook instead of waiting for the result in the submission response.
https://ongsoolabs.com| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/reader/jobs | Submit a Reader request and receive a job ID. |
POST | /api/v1/reader/document/jobs | Submit a public text-layer PDF Document request and receive a job ID. |
POST | /api/v1/summary/jobs | Submit a Summary request and receive a job ID. |
GET | /api/v1/jobs/{jobId} | Read the tenant-scoped job status. |
GET | /api/v1/jobs/{jobId}/result | Retrieve the canonical result after Web settlement completes. |
DELETE | /api/v1/jobs/{jobId} | Request cancellation while the job is queued or running. |
X-API-Key is required on every lifecycle request. Idempotency-Key is required on each submission. Reuse it only for the exact same logical request.
| Status | Description |
|---|---|
created | The durable job was created and activation is being completed. |
queued | The job is waiting for an execution slot. |
running | The job is executing. |
succeeded / partial / failed / cancelled | The operation reached a terminal outcome. Result retrieval may briefly remain pending while credits and webhook delivery are settled. |
reconciliation_required | Web could not safely complete settlement. Do not submit a replacement with a new idempotency key; retry status later or contact support. |
JOB_FINALIZATION_PENDING The result endpoint returns HTTP 409 with retryable=true until Web settlement is complete. Retry the same result URL; do not create another job.
Your verified HTTPS endpoint on port 443Workspace owners configure one HTTPS endpoint and its signing secret in Dashboard Webhooks, select async-job completion events and watchdog.changed, send a signed test, and review delivery history.
Open Dashboard Webhooks →| Event | Description |
|---|---|
job.succeeded | The job completed successfully and its result is available. |
job.partial | The job completed with a partial result. |
job.failed | The job reached a terminal failure. |
job.cancelled | The job was cancelled. |
watchdog.changed | A monitored page changed and its change record is ready. |
| Header | Description |
|---|---|
X-OngsooLabs-Timestamp | Unix time in seconds used by the signature and replay-window check. |
X-OngsooLabs-Signature | Versioned lowercase hexadecimal HMAC-SHA-256 value in the form v1=<digest>. |
X-OngsooLabs-Event-Id | Stable event ID. Use it as the receiver's idempotency key. |
X-OngsooLabs-Delivery-Id | ID for this individual delivery attempt. |
Verification: Read the request body as exact raw bytes, reject timestamps outside five minutes, calculate the signature with the active secret, compare in constant time, and deduplicate by event ID before processing.
Automatic retry: Delivery is attempted immediately and, after failures, at 1 minute, 5 minutes, 30 minutes, and 2 hours: five attempts total. Return any 2xx response within 10 seconds to acknowledge it.
Manual redelivery: History is retained for 30 days. A redelivery sends the same event through the current endpoint and secret with a new delivery ID, timestamp, and signature; it does not rerun the job or Watchdog check, or change credits. Duplicates are possible.
Network boundary: No fixed sender IP or customer IP allowlist is provided. Verify the raw-body HMAC, timestamp, and event ID on every delivery.
Monitor each public webpage URL · every 6 / 12 / 24 hoursRegister public webpages by URL and check their readable body for changes every 6, 12, or 24 hours.
Current availability: Watchdog is verified locally and in the isolated Test environment but is not deployed to Production yet.
Open Watchdog Dashboard →1. Register an absolute public HTTP or HTTPS URL.
2. Choose a 6-, 12-, or 24-hour interval. Optionally enable an AI summary after a change.
3. The first successful check stores only the comparison baseline and sends no change event.
4. Watchdog checks the readable body again on the selected schedule.
5. When the body changes, Watchdog creates a change record and a watchdog.changed event.
6. Review the before and after body, diff, and AI summary in Dashboard, or receive a webhook notification.
| Item | Free allowance or limit |
|---|---|
| Pages monitored at the same time | 3 |
| Free checks | 30 Checks / 30 days |
| Check interval | 6 / 12 / 24 hours |
| Total active monitoring limit | 30 |
The first baseline and each later successful check use one Check. Reservations for checks that do not run are released.
1. Register an absolute public HTTP or HTTPS URL without embedded credentials.
2. Choose a 6-, 12-, or 24-hour check interval. An AI summary is optional and is generated only after a change is detected.
3. The first successful check saves the baseline and sends no change event. Later successful checks add a change record and emit watchdog.changed only when the readable body differs.
Access path: Authenticated Watchdog Dashboard currently provides monitor creation, lookup, and change details. A public Watchdog REST API is not available yet.
Monitoring continues without a webhook. To notify an external service, configure a destination in Dashboard Webhooks and select watchdog.changed. Otherwise, review change history in Watchdog Dashboard.
Open Dashboard Webhooks →The webhook is a lightweight change notification. It omits the URL, changed body, diff, and AI summary so personal data and large page content are not pushed in the notification. Review the actual change in authenticated Watchdog history.
| Field | Description |
|---|---|
id | The top-level id and X-OngsooLabs-Event-Id are the same webhook event identifier. Use it for deduplication. |
createdAt | The time the webhook event was created after change settlement. |
data.eventId | The source Watchdog event identifier. |
data.monitorId | The identifier of the monitor that detected the change. |
data.runId | The identifier of the check run that detected the change. |
data.status | Indicates that a change was detected. The current value is changed. |
data.completedAt | The time the check run actually completed. |
data.monitorId matches the Monitor ID shown under monitor settings and details in Watchdog Dashboard. Enter it in the search field to find that monitor.
The webhook is a signal to review a change record, not the detailed content itself.
1. Receive watchdog.changed and verify its signature.
2. Skip events already processed by top-level id or X-OngsooLabs-Event-Id.
3. Open the monitor identified by data.monitorId in Watchdog Dashboard.
4. Review the before and after body, diff, and optional AI summary in change history.
Change details are currently available only in authenticated Dashboard. There is no public API for an external system to retrieve the detailed body automatically.
| Item | Guaranteed behavior |
|---|---|
| Duplicate delivery | Automatic retries and manual redelivery can deliver the same event more than once. |
| Deduplication key | Use X-OngsooLabs-Event-Id or the identical top-level id. It remains stable during manual redelivery. |
| Delivery order | Retries and manual redelivery can change arrival order, so receivers must not depend on delivery order. |
| Successful acknowledgement | Any HTTP 2xx response returned within 10 seconds is accepted as success. |
| Automatic retry | After the initial delivery fails, retries occur after 1 minute, 5 minutes, 30 minutes, and 2 hours. Including the initial delivery, at most five attempts are made. |
| Timestamp relationship | data.completedAt is the check completion time, createdAt is event creation after settlement, and X-OngsooLabs-Timestamp is the time of each delivery attempt. |
Signature verification: Calculate HMAC-SHA-256 from the raw request-body bytes and timestamp, then compare in constant time. View signature and retry guide →
| State | Description |
|---|---|
submitting | The registration request is being processed. |
baselining | The first baseline is being created. No change event is sent during this step. |
active | The page is being checked on the selected schedule. |
paused | Scheduled checks are paused. |
failed | The latest registration or check did not complete. Review the last error in Dashboard. |
When an error occurs, review the existing monitor state and last error first. Do not register the same URL as a duplicate monitor.
Use Watchdog Dashboard for monitor setup and change details, Dashboard Webhooks for external notifications, and the shared webhook section on this page for signature and retry rules.
COMMON REFERENCE
Gateway errors use the Reader error envelope with usage.credits = 0. Reader-originated errors listed in the downloaded OpenAPI can also be returned after the Gateway accepts a request.
| HTTP | Error code | Description |
|---|---|---|
| 400 | INVALID_REQUEST | The request or Idempotency-Key format is invalid. |
| 401 | INVALID_API_KEY | X-API-Key is missing, inactive, or invalid. |
| 403 | USAGE_EXHAUSTED | No Direct credit is currently available for the Workspace. |
| 409 | IDEMPOTENCY_KEY_CONFLICT | The same Idempotency-Key was used with a different method, path, or body. |
| 413 | REQUEST_BODY_TOO_LARGE | The request body exceeded the Direct Gateway ingress limit. |
| 429 | RATE_LIMITED | The ingress, credential, or Workspace limit was reached. Honor Retry-After. |
| 503 | TEMPORARY_UNAVAILABLE | The Gateway could not safely determine delivery or credit settlement. Retry the same operation with the same Idempotency-Key. |
Retry: Retry only when error.retryable is true. Honor Retry-After on 429, and reuse the same Idempotency-Key only for the same logical Direct POST operation.
Privacy: Submit only public HTTPS webpages or public text-layer PDF URLs. Authentication, cookies, arbitrary headers, paywall bypass, file upload, OCR, DOCX, and encrypted PDFs are not supported.
Support: For a request-specific problem, send the response X-Request-Id or Reader id to support@ongsoolabs.com. Send a source URL only when support explicitly requests it through an approved path.