{"openapi":"3.1.0","info":{"title":"Vooks Public Catalog API","version":"1.0.0","summary":"Read the Vooks children's library and its published pricing.","description":"Read-only access to the Vooks library of animated read-along storybooks, audiobooks\nand ebooks for children roughly ages 2 to 8, plus the published subscription plans.\n\nNo API key is required for reads. Every response carries RateLimit headers; the limit\nis 600 requests per minute per client per edge location. Errors are RFC 9457\n`application/problem+json` with a machine-readable `code`.\n\nA frozen sandbox with the same response shapes lives under `/sandbox`, so an\nintegration can be exercised before it points at the live library.","termsOfService":"https://www.vooks.com/terms-of-service/","contact":{"name":"Vooks support","email":"support@vooks.com","url":"https://www.vooks.com/developers"},"license":{"name":"Vooks API terms","url":"https://www.vooks.com/terms-of-service/"}},"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"},{"url":"https://www.vooks.com/api/v1/sandbox","description":"Sandbox. A fixed, tiny catalog that never changes and never touches the live library. No credential needed. Serves the root, /titles, /topics and /plans."}],"externalDocs":{"description":"Developer guide","url":"https://www.vooks.com/developers"},"security":[{}],"tags":[{"name":"Catalog","description":"Titles and the topics they are filed under."},{"name":"Pricing","description":"Published subscription plans and trial terms."},{"name":"Bulk","description":"Batch reads and asynchronous catalog exports."},{"name":"Sandbox","description":"Fixed test data with production response shapes."}],"paths":{"/":{"get":{"operationId":"getServiceRoot","security":[{}],"tags":["Catalog"],"summary":"Describe the API","description":"Returns the API's version, its endpoint map, the versioning and rate-limit policies, and the date the catalog index was generated. Start here to discover the surface without reading this spec.","responses":{"200":{"description":"The service description.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceRoot"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds given in Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/titles":{"get":{"operationId":"listTitles","security":[{}],"tags":["Catalog"],"summary":"Search and filter titles","description":"Returns a cursor-paginated page of titles. Combine `q`, `age`, `topic`, `language` and `audio` to narrow the library; every filter is applied before pagination, so `pagination.total` is the true count for the query.","parameters":[{"name":"q","in":"query","required":false,"description":"Free-text search across title, subtitle, author, illustrator, summary and topic. Case-insensitive substring match, up to 100 characters.","schema":{"type":"string","maxLength":100}},{"name":"age","in":"query","required":false,"description":"A child's age in whole years. Returns only titles whose published age range contains it, so age=5 matches a 4-8 title but not a 6-9 one.","schema":{"type":"integer","minimum":0,"maximum":18}},{"name":"topic","in":"query","required":false,"description":"A topic slug from GET /topics, for example animals or counting.","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"Narration language of the title.","schema":{"type":"string","enum":["english","hindi","spanish"]}},{"name":"audio","in":"query","required":false,"description":"True to return only titles that also play as audio-only, for screen-free listening.","schema":{"type":"boolean"}},{"name":"sort","in":"query","required":false,"description":"`title` sorts alphabetically by title, `recent` sorts by most recently updated.","schema":{"type":"string","enum":["title","recent"],"default":"title"}},{"name":"limit","in":"query","required":false,"description":"How many records to return, 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","required":false,"description":"The opaque `pagination.next_cursor` from the previous page. Omit it to start at the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of titles.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TitlePage"}}}},"400":{"description":"A query parameter was rejected; `errors[].parameter` names it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/titles/{slug}":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"getTitle","security":[{}],"tags":["Catalog"],"summary":"Fetch one title","description":"Returns a single title by its slug, including the long description. This endpoint reads the live catalog rather than the search index, so it never serves a snapshot.","parameters":[{"name":"slug","in":"path","required":true,"description":"The title's URL slug, as returned in `data[].slug` by listTitles.","schema":{"type":"string"}}],"responses":{"200":{"description":"The title.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TitleDetail"}}}},"404":{"description":"No published title has that slug.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"The catalog service was unreachable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/topics":{"get":{"operationId":"listTopics","security":[{}],"tags":["Catalog"],"summary":"List the topic facets","description":"Returns every topic slug that can be passed to listTitles, with how many titles carry it. Use this instead of guessing topic names.","parameters":[{"name":"limit","in":"query","required":false,"description":"How many records to return, 1 to 100. Defaults to 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"The opaque `pagination.next_cursor` from the previous page. Omit it to start at the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of topics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicPage"}}}},"400":{"description":"A pagination parameter was rejected.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/plans":{"get":{"operationId":"listPlans","security":[{}],"tags":["Pricing"],"summary":"List subscription plans","description":"Returns every published plan with its price, billing interval, audience and trial length, plus the school and district option, which is quoted rather than priced.","responses":{"200":{"description":"The published plans.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanList"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/batch":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"post":{"operationId":"runBatch","security":[{}],"tags":["Bulk"],"summary":"Run several reads in one request","description":"Takes up to 20 GET operations against this API and returns each one's status and body. A failing operation is reported in its own result rather than failing the batch.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}}},"responses":{"200":{"description":"One result per operation, in request order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"description":"The operations array was missing, empty or too long.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/exports":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"post":{"operationId":"createCatalogExport","tags":["Bulk"],"summary":"Start a catalog export","description":"Starts an asynchronous export of every title matching the given filters and returns 202 with a job to poll. Assembling the whole catalog does not belong inside a request an agent is waiting on.","security":[{"vooksOAuth":["catalog:export"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"A client-chosen key, 8 to 200 characters, scoped to your client. The job id derives from this key and the filters together, so repeating the identical request always yields the same job. Reusing one key with different filters is not a conflict: it addresses a different job.","schema":{"type":"string","minLength":8,"maxLength":200}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportRequest"}}}},"responses":{"202":{"description":"The job was accepted. Poll the URL in the Location header; the work is usually already finished.","headers":{"Location":{"description":"Where to poll for the job's status.","schema":{"type":"string","format":"uri"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"The Idempotency-Key header was missing or a filter was rejected.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No access token. The WWW-Authenticate header names the protected-resource metadata.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The token is valid but does not carry the catalog:export scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/jobs/{id}":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"getJob","security":[{}],"tags":["Bulk"],"summary":"Poll an export job","description":"Returns the job. The id carries its own filters, so a job is reconstructed from the id rather than looked up, and never expires.","parameters":[{"name":"id","in":"path","required":true,"description":"The job id returned by createCatalogExport. An opaque base64url string; do not parse it, pass back exactly what you were given.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,1024}$"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"404":{"description":"That id was not issued by this API.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/exports/{id}":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"getCatalogExport","security":[{}],"tags":["Bulk"],"summary":"Download a finished export","description":"Returns the export: every title matching the filters the job was started with, unpaginated. Recomputed from the id on each request, so it does not expire.","parameters":[{"name":"id","in":"path","required":true,"description":"The job id returned by createCatalogExport. An opaque base64url string; do not parse it, pass back exactly what you were given.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,1024}$"}}],"responses":{"200":{"description":"The export.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TitleExport"}}}},"404":{"description":"That id was not issued by this API.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"getSandboxRoot","security":[{}],"tags":["Sandbox"],"summary":"Describe the sandbox","description":"Returns the sandbox's endpoint map and states plainly that nothing under it touches the live library. Start here before pointing an integration at production.","responses":{"200":{"description":"The sandbox description.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxRoot"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox/topics":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"listSandboxTopics","security":[{}],"tags":["Sandbox"],"summary":"List the sandbox topic facets","description":"The same shape as listTopics over the fixed sandbox catalog, so topic filtering can be exercised against known counts.","parameters":[{"name":"limit","in":"query","required":false,"description":"How many records to return, 1 to 100. Defaults to 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"The opaque `pagination.next_cursor` from the previous page. Omit it to start at the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of sandbox topics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicPage"}}}},"400":{"description":"A pagination parameter was rejected.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox/titles":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"listSandboxTitles","security":[{}],"tags":["Sandbox"],"summary":"Search the sandbox catalog","description":"The same shape as listTitles over four fixed titles that never change. Use it to build and test an integration without reading the live library.","parameters":[{"name":"q","in":"query","required":false,"description":"Free-text search across title, subtitle, author, illustrator, summary and topic. Case-insensitive substring match, up to 100 characters.","schema":{"type":"string","maxLength":100}},{"name":"age","in":"query","required":false,"description":"A child's age in whole years. Returns only titles whose published age range contains it, so age=5 matches a 4-8 title but not a 6-9 one.","schema":{"type":"integer","minimum":0,"maximum":18}},{"name":"topic","in":"query","required":false,"description":"A topic slug from GET /topics, for example animals or counting.","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"Narration language of the title.","schema":{"type":"string","enum":["english","hindi","spanish"]}},{"name":"audio","in":"query","required":false,"description":"True to return only titles that also play as audio-only, for screen-free listening.","schema":{"type":"boolean"}},{"name":"sort","in":"query","required":false,"description":"`title` sorts alphabetically by title, `recent` sorts by most recently updated.","schema":{"type":"string","enum":["title","recent"],"default":"title"}},{"name":"limit","in":"query","required":false,"description":"How many records to return, 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","required":false,"description":"The opaque `pagination.next_cursor` from the previous page. Omit it to start at the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of sandbox titles.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxTitlePage"}}}},"400":{"description":"A query parameter was rejected.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox/plans":{"servers":[{"url":"https://www.vooks.com/api/v1","description":"Production"}],"get":{"operationId":"listSandboxPlans","security":[{}],"tags":["Sandbox"],"summary":"List plans in the sandbox","description":"The same shape as listPlans. The prices are the real published ones, because there is nothing to protect about them.","responses":{"200":{"description":"The plans, marked as sandbox.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxPlanList"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"securitySchemes":{"vooksOAuth":{"type":"oauth2","description":"OAuth 2.0 against the Vooks authorization server. Reads need no token; a token raises the rate limit from 600 to 3,000 requests a minute and is required for catalog exports. Metadata: https://www.vooks.com/.well-known/oauth-authorization-server","flows":{"clientCredentials":{"tokenUrl":"https://www.vooks.com/oauth/token","scopes":{"catalog:read":"Read the published catalog: search titles, fetch one title, list topics.","pricing:read":"Read the published subscription plans, their prices and the trial terms.","catalog:export":"Start and download bulk catalog exports. The only scope that writes anything."}},"authorizationCode":{"authorizationUrl":"https://www.vooks.com/oauth/authorize","tokenUrl":"https://www.vooks.com/oauth/token","scopes":{"catalog:read":"Read the published catalog: search titles, fetch one title, list topics.","pricing:read":"Read the published subscription plans, their prices and the trial terms.","catalog:export":"Start and download bulk catalog exports. The only scope that writes anything."}}}}},"schemas":{"Problem":{"type":"object","description":"An RFC 9457 problem document. Every non-2xx response from this API uses it.","required":["type","title","status","detail","code"],"properties":{"type":{"type":"string","format":"uri","description":"A link to this error in the developer docs."},"title":{"type":"string","description":"A short, human-readable summary of the problem."},"status":{"type":"integer","description":"The HTTP status code, repeated in the body."},"detail":{"type":"string","description":"What went wrong with this specific request."},"code":{"type":"string","description":"The stable machine-readable error code. Branch on this, not on `title`.","enum":["not_found","invalid_parameter","method_not_allowed","idempotency_key_required","internal_error","unauthorized","insufficient_scope","rate_limited","upstream_error"]},"documentation":{"type":"string","format":"uri","description":"The developer guide."},"instance":{"type":"string","description":"The path that produced the error."},"errors":{"type":"array","description":"Present on invalid_parameter: one entry per rejected parameter.","items":{"type":"object","required":["parameter","detail"],"properties":{"parameter":{"type":"string","description":"The name of the rejected parameter."},"detail":{"type":"string","description":"Why it was rejected."}}}}}},"AgeRange":{"type":"object","description":"The publisher's recommended age range, in whole years, inclusive at both ends.","required":["min","max"],"properties":{"min":{"type":"integer","description":"Youngest recommended age."},"max":{"type":"integer","description":"Oldest recommended age."}}},"Title":{"type":"object","description":"One title in the Vooks library.","required":["slug","title","url","topics","audio_available"],"properties":{"slug":{"type":"string","description":"Stable identifier, also the last path segment of `url`."},"title":{"type":"string","description":"The title as published."},"subtitle":{"type":["string","null"],"description":"Subtitle, when the book has one."},"author":{"type":["string","null"],"description":"Author credit."},"illustrator":{"type":["string","null"],"description":"Illustrator credit."},"publisher":{"type":["string","null"],"description":"Publisher credit."},"summary":{"type":["string","null"],"description":"One or two sentences describing the book."},"age_range":{"description":"Parsed age range, or null when the publisher gave a non-numeric band.","oneOf":[{"$ref":"#/components/schemas/AgeRange"},{"type":"null"}]},"age_label":{"type":["string","null"],"description":"The age band exactly as published, e.g. \"4-8\"."},"lexile":{"type":["string","null"],"description":"Lexile measure, e.g. \"410L\" or \"NP\"."},"language":{"type":["string","null"],"description":"Narration language.","examples":["english","hindi","spanish"]},"duration_seconds":{"type":["integer","null"],"description":"Running time of the animated reading, in seconds."},"audio_available":{"type":"boolean","description":"Whether the title also plays audio-only, for screen-free listening."},"topics":{"type":"array","description":"Topic slugs this title carries. Every value appears in GET /topics.","items":{"type":"string"}},"cover_url":{"type":["string","null"],"format":"uri","description":"Cover image."},"url":{"type":"string","format":"uri","description":"Where a subscriber watches the title."},"updated_at":{"type":["string","null"],"format":"date-time","description":"When the title was last changed upstream."}}},"TitleDetail":{"allOf":[{"$ref":"#/components/schemas/Title"},{"type":"object","properties":{"description":{"type":["string","null"],"description":"The publisher's full description. Only the single-title endpoint returns it."}}}],"description":"A title with its long description, as returned by getTitle."},"Pagination":{"type":"object","description":"Cursor pagination. Follow `next_cursor` until `has_more` is false.","required":["limit","total","has_more","next_cursor"],"properties":{"limit":{"type":"integer","description":"How many records this page holds at most."},"total":{"type":"integer","description":"Total records matching the query, across all pages."},"has_more":{"type":"boolean","description":"Whether another page follows."},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to fetch the next page. Null on the last page."}}},"TitlePage":{"type":"object","description":"A page of titles.","required":["data","pagination"],"properties":{"data":{"type":"array","description":"The titles on this page.","items":{"$ref":"#/components/schemas/Title"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"catalog_generated_at":{"type":"string","format":"date","description":"The day the search index was built from the live catalog."}}},"SandboxTitlePage":{"allOf":[{"$ref":"#/components/schemas/TitlePage"},{"type":"object","properties":{"sandbox":{"type":"boolean","description":"Always true, so sandbox data is never mistaken for live."}}}],"description":"A page of sandbox titles."},"Topic":{"type":"object","description":"A topic facet.","required":["slug","name","title_count"],"properties":{"slug":{"type":"string","description":"Pass this to listTitles as `topic`."},"name":{"type":"string","description":"Human-readable topic name."},"title_count":{"type":"integer","description":"How many titles carry this topic."}}},"TopicPage":{"type":"object","description":"A page of topics.","required":["data","pagination"],"properties":{"data":{"type":"array","description":"The topics on this page.","items":{"$ref":"#/components/schemas/Topic"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"catalog_generated_at":{"type":"string","format":"date","description":"When the index was built."}}},"Plan":{"type":"object","description":"A published subscription plan.","required":["id","name","audience","interval","price","trial_days"],"properties":{"id":{"type":"string","description":"Stable plan identifier."},"name":{"type":"string","description":"The plan's display name."},"audience":{"type":"string","enum":["consumer","teacher"],"description":"Who the plan is for. Teacher rates require verification."},"interval":{"type":"string","enum":["year","month"],"description":"Billing interval."},"price":{"type":"object","description":"The recurring price.","required":["amount","currency"],"properties":{"amount":{"type":"number","description":"Amount charged each interval."},"currency":{"type":"string","description":"ISO 4217 currency code."}}},"trial_days":{"type":"integer","description":"Length of the free trial, in days."},"signup_url":{"type":"string","format":"uri","description":"Where to subscribe."},"description":{"type":"string","description":"What the plan includes."}}},"QuotedPlan":{"type":"object","description":"An offering with no published price, quoted per customer.","required":["id","name","pricing"],"properties":{"id":{"type":"string","description":"Stable identifier."},"name":{"type":"string","description":"Display name."},"audience":{"type":"string","description":"Who it is for."},"pricing":{"type":"string","enum":["quote"],"description":"Always \"quote\": there is no list price."},"contact":{"type":"string","description":"Where to ask for a quote."},"quote_url":{"type":"string","format":"uri","description":"The quote request form."},"description":{"type":"string","description":"What the offering covers."}}},"PlanList":{"type":"object","description":"Every published plan, plus the quoted institutional option.","required":["data"],"properties":{"data":{"type":"array","description":"Priced plans.","items":{"$ref":"#/components/schemas/Plan"}},"quoted":{"type":"array","description":"Offerings quoted per customer.","items":{"$ref":"#/components/schemas/QuotedPlan"}},"currency":{"type":"string","description":"Currency every price is quoted in."},"trial_days":{"type":"integer","description":"Trial length shared by every paid plan."},"pricing_page":{"type":"string","format":"uri","description":"The human pricing page."},"pricing_markdown":{"type":"string","format":"uri","description":"The same page as markdown."}}},"SandboxPlanList":{"allOf":[{"$ref":"#/components/schemas/PlanList"},{"type":"object","properties":{"sandbox":{"type":"boolean","description":"Always true."}}}],"description":"Plans served from the sandbox."},"BatchOperation":{"type":"object","description":"One read to run as part of a batch.","required":["path"],"properties":{"id":{"type":"string","description":"Your label for this operation, echoed back in the result."},"method":{"type":"string","enum":["GET"],"description":"Only GET is accepted."},"path":{"type":"string","description":"A path under /api/v1, including its query string, e.g. \"/titles?age=5&limit=3\"."}}},"BatchRequest":{"type":"object","description":"Up to 20 reads to run in one round trip.","required":["operations"],"properties":{"operations":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/BatchOperation"},"description":"The reads."}}},"BatchResult":{"type":"object","description":"The outcome of one operation.","required":["id","status"],"properties":{"id":{"type":"string","description":"The label you gave the operation."},"status":{"type":"integer","description":"The HTTP status that operation would have returned."},"body":{"description":"The body that operation would have returned, parsed."}}},"BatchResponse":{"type":"object","description":"One result per operation, in request order.","required":["results"],"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchResult"},"description":"The results."}}},"ExportRequest":{"type":"object","description":"What to export. Omit the body to export the whole published catalog.","properties":{"resource":{"type":"string","enum":["titles"],"description":"The only exportable resource."},"filters":{"type":"object","description":"The same filters listTitles accepts, as an object, e.g. {\"language\":\"spanish\"}.","additionalProperties":{"type":"string"}}}},"Job":{"type":"object","description":"An asynchronous export job.","required":["id","status","resource","computed_at","title_count","result_url"],"properties":{"id":{"type":"string","description":"The job id, an opaque base64url string. Poll /jobs/{id} with it."},"status":{"type":"string","enum":["succeeded"],"description":"Always `succeeded`. The filter runs in memory, so the job is finished by the time the 202 is written, and an export that cannot run answers 500 rather than returning a job."},"resource":{"type":"string","enum":["titles"],"description":"What is being exported."},"computed_at":{"type":"string","format":"date-time","description":"When this answer was computed. A job is reconstructed from its id rather than stored, so there is no separate creation time to report."},"title_count":{"type":"integer","description":"How many titles the export holds."},"result_url":{"type":"string","format":"uri","description":"Where to download the export."},"error":{"type":"null","description":"Always null. A job that cannot run answers 500 instead."}}},"TitleExport":{"type":"object","description":"A finished export: every matching title, unpaginated.","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Title"},"description":"The exported titles."}}},"SandboxRoot":{"type":"object","description":"The sandbox's self-description, returned by GET /sandbox.","required":["name","endpoints","sandbox"],"properties":{"name":{"type":"string","description":"The sandbox's name."},"description":{"type":"string","description":"What the sandbox contains and does not touch."},"endpoints":{"type":"object","description":"A map of name to URL for every sandbox endpoint.","additionalProperties":{"type":"string"}},"sandbox":{"type":"boolean","description":"Always true."}}},"ServiceRoot":{"type":"object","description":"The API's self-description, returned by GET /.","required":["name","version","openapi","documentation","endpoints"],"properties":{"name":{"type":"string","description":"The API's name."},"version":{"type":"string","description":"The major version this base URL serves."},"description":{"type":"string","description":"What the API covers."},"openapi":{"type":"string","format":"uri","description":"This document."},"documentation":{"type":"string","format":"uri","description":"The developer guide."},"terms_of_service":{"type":"string","format":"uri","description":"Terms that govern use."},"contact":{"type":"string","description":"Where to reach a human."},"catalog_generated_at":{"type":"string","format":"date","description":"When the index was built."},"authentication":{"type":"string","description":"What, if anything, needs a credential."},"versioning":{"type":"string","description":"The versioning and deprecation promise."},"rate_limit":{"type":"string","description":"The published limit."},"sandbox":{"type":"string","format":"uri","description":"The sandbox base URL."},"endpoints":{"type":"object","description":"A map of name to URL for every endpoint.","additionalProperties":{"type":"string"}}}}}}}