Skip to content

REST Channel

Standard HTTP/JSON. If your app can make a GET request, it can query the directory. The REST channel comes with an OpenAPI spec, interactive docs, conditional requests, and streaming exports.

Scribe enables the REST channel by default. Key endpoints:

URLWhat you get
/apiOpenAPI UI (browser) or spec (JSON/YAML via content negotiation)
/api/entries/{type}Collection search
/api/entries/{type}/{id}Single entry lookup
/api/entries/{type}/{id}/changesPer-entry change history
/api/changesGlobal change feed

Browse /api in a browser for interactive API docs with code samples, live testing, and schema details. Download the spec at /api.json or /api.yaml.

REST paths and OpenAPI identifiers are derived from entry type names using singular/plural normalization. Startup enforces strict uniqueness across:

  • REST paths (/api/entries/{type}, /api/entries/{type}/{id}, /api/entries/{type}/{id}/changes)
  • OpenAPI operationId values (search*, lookup*, get*Changes)
  • OpenAPI schema component names (Entry_*, SearchResponse_*)

If two configured types collide after normalization (for example user and users), startup fails before serving traffic.

OpenAPI component names are sanitized to a conservative format for code generators: ^[A-Za-z][A-Za-z0-9_]*$. Reserved tokens (for example class) are suffixed (for example class_type). If sanitization causes a component-name collision, startup fails.

Filters auto-detect format. Use whichever fits your context:

FormatDetectionExample
JSONStarts with { or [{"cn":"john"}
LDAPStarts with ((cn=john*)
FleXDefaultcn = john
SCIMFallbackcn eq "john"
Terminal window
# Spaces in filter values are URL-encoded by curl when using --data-urlencode,
# or quote the entire URL as shown here
curl "/api/entries/users?filter=department%3DEngineering%20AND%20active%3Dtrue"
ValueReturns
cn,mail,snSpecific attributes
*All user attributes
+All operational attributes
1.1No attributes (IDs only)
Terminal window
?sort=cn # Ascending
?sort=-cn # Descending
?sort=sn,-cn # Multiple keys

Relay-style cursor pagination:

ParameterDirection
first / afterForward
last / beforeBackward
limitAlias — resolves to first or last based on cursor
Terminal window
# First page
curl "/api/entries/users?first=25"
# Next page (use endCursor from previous response)
curl "/api/entries/users?first=25&after=eyJjbiI6Impv..."

Lookup endpoints accept any identifier format. DN values must be URL-encoded in paths.

Poll efficiently with ETags:

Terminal window
# First request returns ETag
curl -I "/api/entries/users/$UUID"
# ETag: W/"abc123..."
# Subsequent requests — 304 when unchanged
curl -H 'If-None-Match: W/"abc123..."' "/api/entries/users/$UUID"

If-Modified-Since is also supported. Search responses include Cache-Control: no-store; lookup responses include Cache-Control: private, max-age=0, must-revalidate.

Query changes via the global feed (/api/changes) or per-entry (/api/entries/{type}/{id}/changes).

Terminal window
# Changes in the last 24 hours
curl "/api/changes?range=24h&first=50"
# MODIFY events that changed the mail attribute
curl "/api/changes?type=modify&affects=mail&since=this week"

Time ranges accept temporal references: ISO timestamps, durations, yesterday, last 3 days, etc.

View an entry at any moment:

Terminal window
curl "/api/entries/users/$ID?at=2024-01-15T10:00:00Z"
curl "/api/entries/users/$ID?at=now-1h"

Change events support three data formats. Use ?include=nodes,patch,pageInfo to select which parts to return. For count-only queries (no data fetch), use ?include=count.

Stream search results to a file by adding filename to any search request:

Terminal window
curl -OJ "/api/entries/users?filename=users.csv&fields=cn,mail,department"

In export mode, Scribe bypasses pagination and streams the full result set.

FormatExtensionNotes
CSV.csvExcel-compatible, RFC 4180
TSV.tsvTab-delimited
JSON.jsonStreaming JSON array
NDJSON.ndjsonNewline-delimited JSON
JSON-seq.json-seqRFC 7464
JSON-LD.jsonldWith @id/@type
LDIF.ldifLDAP interchange format

Exports require an explicit field list — wildcards (*, +) are not allowed. Pass format options as JSON via the export parameter:

Terminal window
# Custom delimiter and null handling
curl -OJ '/api/entries/users?filename=data.csv&fields=cn,mail&export={"delimiter":"|","nulls":"N/A"}'

See Configuration Reference for export limits, delimited format options, and all other REST settings.

Control how the API handles unknown attributes with Prefer: handling=strict (returns 400 with the unknown names) or Prefer: handling=lenient (default — ignores unknowns silently).

See Signals for metrics, Error Handling for error codes.