{ "openapi": "3.1.0", "info": { "title": "WordLift resolve()", "version": "1.0.0", "description": "Map mentions to identities in an explicit dataset, or return unresolved. See docs/resolve-contract.md.", "license": { "name": "Apache-2.0" }, "contact": { "name": "WordLift", "url": "https://wordlift.io/contact-us/", "email": "hello@wordlift.io" }, "x-api-id": "wordlift-resolve", "x-audience": "external-public" }, "servers": [ { "url": "https://api.wordlift.io", "description": "The WordLift API; the account route is metered." } ], "security": [ { "WordLiftKey": [] } ], "paths": { "/accounts/{accountId}/resolve": { "post": { "tags": [ "resolve" ], "summary": "Resolve", "description": "Resolve mentions to identities in `dataset_uri`, or return unresolved.", "operationId": "resolve_v1_resolve_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResolveRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResolveResponse" } } }, "headers": { "X-Wordlift-Cost": { "description": "What the call counts against the monthly allowance of requests: one, plus one per 1,000 characters of text.", "schema": { "type": "integer", "format": "int64" } }, "X-RateLimit-Limit": { "description": "Monthly allowance of the account for resolve().", "schema": { "type": "integer", "format": "int64" } }, "X-RateLimit-Remaining": { "description": "Requests left in the current period.", "schema": { "type": "integer", "format": "int64" } }, "X-RateLimit-Reset": { "description": "Seconds until the allowance resets.", "schema": { "type": "integer", "format": "int64" } } } }, "422": { "description": "The body fails validation (`invalid_request`, with `errors`) or the request is refused: `invalid_span`, `invalid_identity`, `dataset_not_supported`, `dataset_required`, `invalid_dataset`, `unknown_include`, `candidates_not_supported`.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }, "401": { "description": "Missing or invalid WordLift API key (`unauthorized`).", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }, "429": { "description": "Two sources, told apart by the Content-Type. The gateway's allowance block: the account's monthly allowance for resolve() is spent, text/plain body, X-RateLimit-* headers. The engine's bounded queue: the replica has its limit of requests in flight and waiting, application/problem+json `too_many_requests` with Retry-After. Nothing was resolved in either case.", "headers": { "X-RateLimit-Limit": { "description": "Monthly allowance.", "schema": { "type": "integer", "format": "int64" } }, "X-RateLimit-Remaining": { "description": "Always 0 here.", "schema": { "type": "integer", "format": "int64" } }, "X-RateLimit-Reset": { "description": "Seconds until the allowance resets.", "schema": { "type": "integer", "format": "int64" } }, "Retry-After": { "description": "Seconds to wait before retrying (engine's queue).", "schema": { "type": "integer", "format": "int64" } } }, "content": { "text/plain": { "schema": { "type": "string", "description": "A sentence naming the limit, the resource and the seconds until reset." } }, "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }, "503": { "description": "The engine is loading the account's knowledge graph (`dataset_warming`: Retry-After and the body's `retry_after_s` carry the same seconds, the header is authoritative) or has no index yet (`dataset_unavailable`; the 502 of the same code is the caller's graph failing to read).", "headers": { "Retry-After": { "description": "Seconds to wait before retrying.", "schema": { "type": "integer", "format": "int64" } } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }, "502": { "description": "The account's knowledge graph could not be read (`dataset_unavailable`, `dataset_uri` names the world); a retry can help.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } }, "403": { "description": "The key does not belong to this account.", "content": { "text/plain": { "schema": { "type": "string" } } } } }, "security": [ { "WordLiftKey": [] } ], "parameters": [ { "name": "accountId", "in": "path", "required": true, "description": "Your WordLift account id: the `accountId` of GET /accounts/me with the same key. A key used with another account's id is answered 403.", "schema": { "type": "integer", "format": "int64" } } ] } } }, "components": { "schemas": { "MentionResolution": { "properties": { "text": { "type": "string", "title": "Text" }, "start": { "type": "integer", "title": "Start", "format": "int32" }, "end": { "type": "integer", "title": "End", "format": "int32" }, "type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Type" }, "status": { "type": "string", "title": "Status", "description": "resolved | unresolved" }, "entity": { "anyOf": [ { "$ref": "#/components/schemas/ResolvedEntity" }, { "type": "null" } ] }, "score": { "anyOf": [ { "type": "number", "format": "double" }, { "type": "null" } ], "title": "Score", "description": "Decision score; not a calibrated probability" }, "reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Reason" }, "candidates": { "anyOf": [ { "items": { "additionalProperties": true, "type": "object" }, "type": "array" }, { "type": "null" } ], "title": "Candidates" }, "evidence": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "title": "Evidence" }, "dataset_uri": { "type": [ "string", "null" ], "description": "The world that answered this mention, e.g. `wordlift://dataset/me` or `wikidata://public`." }, "signals": { "anyOf": [ { "$ref": "#/components/schemas/DecisionSignals" }, { "type": "null" } ] } }, "type": "object", "required": [ "text", "start", "end", "status" ], "title": "MentionResolution" }, "ResolveCandidate": { "properties": { "id": { "type": "string", "title": "Id", "description": "Identity in the dataset: Q312, wd:Q312 or a Wikidata entity URI" }, "label": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Label" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Description" }, "types": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "title": "Types" }, "score": { "anyOf": [ { "type": "number", "format": "double" }, { "type": "null" } ], "title": "Score", "description": "Caller's retrieval score; informational" } }, "type": "object", "required": [ "id" ], "title": "ResolveCandidate" }, "ResolveMention": { "properties": { "text": { "type": "string", "minLength": 1, "title": "Text" }, "start": { "type": "integer", "minimum": 0.0, "title": "Start", "format": "int32" }, "end": { "type": "integer", "minimum": 1.0, "title": "End", "format": "int32" }, "type": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Type", "description": "Caller's type hint, e.g. Person, Organization" }, "candidates": { "anyOf": [ { "items": { "$ref": "#/components/schemas/ResolveCandidate" }, "type": "array" }, { "type": "null" } ], "title": "Candidates", "description": "Identities retrieved by the caller; if omitted the engine retrieves against dataset_uri" } }, "type": "object", "required": [ "text", "start", "end" ], "title": "ResolveMention" }, "ResolveRequest": { "properties": { "text": { "type": "string", "maxLength": 100000, "minLength": 1, "title": "Text" }, "dataset_uri": { "type": "string", "title": "Dataset Uri", "description": "The world to resolve against: `wikidata://public` (default), `wordlift://dataset/me` (your WordLift graph, read with your key), `inline` (with `dataset`), or a comma-separated ordered list such as `wordlift://dataset/me,wikidata://public` (your entities first, Wikidata for the rest).", "default": "wikidata://public" }, "language": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Language", "description": "ISO 639-1; auto-detected if omitted" }, "mentions": { "anyOf": [ { "items": { "$ref": "#/components/schemas/ResolveMention" }, "type": "array" }, { "type": "null" } ], "title": "Mentions", "description": "Explicit spans; if omitted the engine detects mentions" }, "include": { "items": { "type": "string" }, "type": "array", "title": "Include", "description": "Diagnostics: candidates, evidence" }, "confidence": { "type": "number", "maximum": 1.0, "minimum": 0.0, "title": "Confidence", "description": "NER threshold when the engine detects mentions", "default": 0.5, "format": "double" }, "dataset": { "anyOf": [ { "$ref": "#/components/schemas/InlineDataset" }, { "type": "null" } ], "description": "An inline vocabulary (up to 5,000 entities): the answer is one of these ids or unresolved. Implies dataset_uri `inline`." } }, "type": "object", "required": [ "text" ], "title": "ResolveRequest" }, "ResolveResponse": { "properties": { "mentions": { "items": { "$ref": "#/components/schemas/MentionResolution" }, "type": "array", "title": "Mentions" }, "dataset_uri": { "type": "string", "title": "Dataset Uri" }, "language": { "type": "string", "title": "Language" }, "processing_time_ms": { "type": "number", "title": "Processing Time Ms", "format": "double" }, "engine": { "type": "string", "title": "Engine", "default": "content-analysis-v3" } }, "type": "object", "required": [ "mentions", "dataset_uri", "language", "processing_time_ms" ], "title": "ResolveResponse" }, "ResolvedEntity": { "properties": { "id": { "type": "string", "title": "Id" }, "label": { "type": "string", "title": "Label" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Description" }, "types": { "items": { "type": "string" }, "type": "array", "title": "Types" }, "same_as": { "items": { "type": "string" }, "type": "array", "title": "Same As" } }, "type": "object", "required": [ "id", "label" ], "title": "ResolvedEntity" }, "ValidationError": { "properties": { "loc": { "items": { "anyOf": [ { "type": "string" }, { "type": "integer", "format": "int32" } ] }, "type": "array", "title": "Location" }, "msg": { "type": "string", "title": "Message" }, "type": { "type": "string", "title": "Error Type" }, "input": { "title": "Input" }, "ctx": { "type": "object", "title": "Context" } }, "type": "object", "required": [ "loc", "msg", "type" ], "title": "ValidationError" }, "UserEntity": { "type": "object", "title": "UserEntity", "description": "An entity of your own vocabulary. `id` is echoed back as given.", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" } }, "description": { "type": [ "string", "null" ] }, "types": { "type": "array", "items": { "type": "string" }, "description": "schema.org types, e.g. Organization, Person, Place" }, "same_as": { "type": "array", "items": { "type": "string" } } }, "required": [ "id", "name" ] }, "InlineDataset": { "type": "object", "title": "InlineDataset", "properties": { "entities": { "type": "array", "items": { "$ref": "#/components/schemas/UserEntity" }, "maxItems": 5000 } }, "required": [ "entities" ] }, "DecisionSignals": { "type": "object", "title": "DecisionSignals", "description": "How the decision was reached; present whenever the engine ranked candidates.", "properties": { "path": { "type": "string", "description": "`fast` (exact dictionary hit, model skipped), `reranked` (public world), `vocabulary` (your dataset)" }, "retrieval_prior": { "type": [ "number", "null" ], "format": "double" }, "match_probability": { "type": [ "number", "null" ], "format": "double" }, "rescued": { "type": "boolean" } }, "required": [ "path", "rescued" ] }, "Problem": { "type": "object", "title": "Problem", "description": "RFC 9457 Problem Details, Content-Type application/problem+json. `code` is the engine's stable error code and `type` is derived from it; extension members carry what the route knows (dataset_uri, mention, accepted, retry_after_s, errors).", "properties": { "type": { "type": "string", "format": "uri", "description": "https://docs.wordlift.io/problems/, the page describing the code." }, "title": { "type": "string" }, "status": { "type": "integer", "format": "int32" }, "detail": { "type": "string", "description": "A human-readable sentence, when the engine has one." }, "instance": { "type": "string", "description": "The request path." }, "code": { "type": "string", "description": "Stable error code: unauthorized, invalid_request, invalid_span, invalid_identity, dataset_not_supported, dataset_required, invalid_dataset, unknown_include, candidates_not_supported, too_many_requests, dataset_warming, dataset_unavailable; status-only codes not_found, internal_error, upstream_error, unavailable, upstream_timeout." }, "errors": { "type": "array", "description": "On invalid_request: one entry per failing field.", "items": { "$ref": "#/components/schemas/ValidationError" } }, "retry_after_s": { "type": "integer", "format": "int64", "description": "On dataset_warming: the seconds of the Retry-After header, repeated for clients that only read the body. The header is authoritative." } }, "required": [ "type", "title", "status", "code" ], "additionalProperties": true } }, "securitySchemes": { "WordLiftKey": { "type": "apiKey", "in": "header", "name": "Authorization", "description": "WordLift API key, sent as `Authorization: Key `" } } } }