REST Channel
Query IdentityScribe via HTTP/JSON with OpenAPI documentation, conditional requests, and cursor pagination.
Overview
Section titled “Overview”The REST channel provides:
- Collection and lookup endpoints with filtering, sorting, and Relay-style pagination
- Change history API — global feed and per-entry history with temporal lookup
- OpenAPI specification with interactive UI (Scalar)
- Conditional requests — ETag/If-None-Match for efficient polling
- Streaming responses — memory-efficient handling of large result sets
Related:
- Configuration Reference — all settings, env vars, and defaults
- Channels Overview — general channel concepts
- GraphQL Channel — alternative query API
- Failures — HTTP status codes and error handling
Quick start
Section titled “Quick start”The REST channel is enabled by default. Access points:
| URL | Description |
|---|---|
/api | OpenAPI UI (HTML) or spec (JSON/YAML via content negotiation) |
/api.json | Download OpenAPI spec as JSON |
/api.yaml | Download OpenAPI spec as YAML |
/openapi.json | Well-known alias for OpenAPI JSON |
/openapi.yaml | Well-known alias for OpenAPI YAML |
/api/entries/{type} | Collection search |
/api/entries/{type}/{id} | Single entry lookup |
/api/entries/{type}/{id}/changes | Per-entry change history |
/api/changes | Global change feed |
OpenAPI documentation
Section titled “OpenAPI documentation”Browse the interactive API documentation at /api. The UI provides:
- Complete endpoint documentation with request/response schemas
- Code samples for curl, JavaScript, TypeScript, and Go
- Live API testing (in dev mode)
- Schema with attribute metadata extensions (
x-scribe-*) - Documented headers, including conditional requests and
Prefer/Preference-Applied
Download the spec: /api?format=json or /api?format=yaml, or use the direct endpoints /api.json and /api.yaml. See API Discovery for programmatic channel and schema discovery.
Query parameters
Section titled “Query parameters”Filter
Section titled “Filter”Filters auto-detect format based on syntax. See Filters Reference for complete syntax.
| Format | Detection | Example |
|---|---|---|
| JSON | Starts with { or [ | {"cn":"john"} |
| LDAP | Starts with ( | (cn=john*) |
| FleX | Default | cn = john |
| SCIM | Fallback | cn eq "john" |
# FleX (recommended)?filter=department=Engineering AND active=true
# JSON (programmatic)?filter={"cn":"john","status":"active"}See Filters Reference for complete syntax.
Fields
Section titled “Fields”Select attributes to return:
| Value | Meaning |
|---|---|
cn,mail,sn | Specific attributes |
* | All user attributes |
+ | All operational attributes |
1.1 | No attributes (IDs only) |
Sort by one or more attributes:
?sort=cn # Ascending?sort=-cn # Descending?sort=sn,-cn # Multiple keysPagination
Section titled “Pagination”Relay-style cursor pagination:
| Parameter | Description |
|---|---|
first / after | Forward pagination |
last / before | Backward pagination |
limit | Alias for first/last |
# First page?first=25
# Next page?first=25&after=eyJjbiI6Impv...Response shape
Section titled “Response shape”Control response content with include:
| Part | Default | Description |
|---|---|---|
nodes | ✓ | Entry objects |
edges | ✗ | {cursor, node} objects |
pageInfo | ✓ | Pagination metadata |
count | ✓ | Total count |
Notes:
- Use
?include=countfor count-only responses (skips entry hydration) - Use
?include=edges,pageInfofor Relay-style responses
?include=count # Count only?include=edges,pageInfo # Relay formatID formats
Section titled “ID formats”Lookup endpoints accept GlobalId, UUID, UOID, or DN. See Entry identifiers for the full format reference.
DN values must be URL-encoded in paths.
Conditional requests
Section titled “Conditional requests”Lookup endpoints support efficient polling with ETag validation:
# First request — get entry and ETagcurl -I "/api/entries/users/$UUID"# ETag: W/"abc123..."
# Subsequent requests — 304 when unchangedcurl -H 'If-None-Match: W/"abc123..."' "/api/entries/users/$UUID"# HTTP/1.1 304 Not ModifiedIf-Modified-Since is also supported as a fallback.
Cache headers:
- Lookup responses include
Cache-Control: private, max-age=0, must-revalidate - Search responses include
Cache-Control: no-store - Lookup responses include
Last-Modifiedwhen available
Request preferences (RFC 7240)
Section titled “Request preferences (RFC 7240)”Control how the API handles unknown attributes referenced in fields, sort, or filter:
Prefer: handling=lenient(default) — unknown attributes are ignoredPrefer: handling=strict— unknown attributes return400 INVALID_ARGUMENTwith the list of unknowns- When explicitly set, responses include
Preference-Applied: handling=lenient|strict
# Strict attribute validationcurl -H 'Prefer: handling=strict' "/api/entries/users?fields=cn,unknownAttr"Change history
Section titled “Change history”Query change history via the global feed or per-entry endpoint.
Time range
Section titled “Time range”# Duration?range=24h
# ISO 8601 interval?range=2024-01-01/2024-01-31
# Natural language?range=yesterday?since=this week?since=last 3 days
# Since/until?since=2024-01-01&until=2024-01-07Filtering
Section titled “Filtering”| Parameter | Description |
|---|---|
type | Event types: add, modify, move, delete |
affects | MODIFY events by changed attributes |
entryType | Filter by entry type (global endpoint only) |
Response shape
Section titled “Response shape”| Part | Description |
|---|---|
nodes | Change events (no cursor) |
edges | {cursor, node} change events (Relay-style) |
pageInfo | Pagination metadata |
count | Total count |
data | Raw event data |
patch | JSON Patch-inspired format (delta semantics) |
merge | JSON Merge Patch-inspired format (delta semantics) |
meta | Event metadata |
Notes:
- Use
?include=countfor count-only responses - Use
?include=edges,pageInfofor Relay-style responses
# Get changes with patch formatcurl "/api/changes?include=nodes,patch,pageInfo&first=50"Temporal lookup
Section titled “Temporal lookup”View an entry at any point in time:
# At specific timestamp?at=2024-04-22T08:43:50Z
# Relative duration?at=1h
# At specific event (cursor from change history)?at=AAFntW9XAAAAAAApQwAAError handling
Section titled “Error handling”REST errors return HTTP status codes with JSON error bodies:
| Status | Kind | Meaning |
|---|---|---|
| 400 | INVALID_ARGUMENT | Invalid request |
| 404 | NOT_FOUND | Entry not found |
| 429 | RESOURCE_EXHAUSTED | Rate limited |
| 503 | UNAVAILABLE | Service busy |
{ "error": { "id": "550e8400-...", "code": "ARGUMENT_INVALID_JSON", "kind": "INVALID_ARGUMENT", "message": "Invalid JSON format for 'filter'." }}See Failures for complete error documentation.
Observability
Section titled “Observability”REST operations emit OpenTelemetry traces:
| Span | Description |
|---|---|
REST.Search | Collection search |
REST.Lookup | Single entry lookup |
REST.History | Change history queries |
Spans include entry type, response shape, and error details.
Related:
- Observability Guide — traces, metrics, and logs
- Monitoring Guide — dashboards and alerting