{"openapi":"3.1.0","info":{"title":"Apostille Finder API","version":"1","description":"Read only JSON API for the Apostille Finder directory. Every response carries `meta.attribution` and `meta.sources`. Each source keeps its own license."},"servers":[{"url":"https://admin-staging.apostilles.fyi/api/v1"}],"paths":{"/listings":{"get":{"summary":"Search and list listings","operationId":"getListings","parameters":[{"name":"q","in":"query","required":false,"description":"Search text, with at least one letter or digit. Matches name, categories, attributes, description and place. Typos fall back to close matches.","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"country","in":"query","required":false,"description":"ISO 3166-1 alpha-2 country code, any case. A country the directory does not cover, as listed in /places, gives 400.","schema":{"type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"region","in":"query","required":false,"description":"Region slug, from /places.","schema":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"}},{"name":"city","in":"query","required":false,"description":"City slug, from /places.","schema":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"}},{"name":"category","in":"query","required":false,"description":"Category slug, from /categories. A parent slug also matches its children.","schema":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"}},{"name":"sort","in":"query","required":false,"description":"`relevance` needs `q` and is the default with it. `name` is the default without `q`. `recent` is newest first.","schema":{"type":"string","enum":["relevance","name","recent"]}},{"name":"limit","in":"query","required":false,"description":"Items per page.","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}},{"name":"cursor","in":"query","required":false,"description":"`page.nextCursor` from the previous response. Opaque. Send the same filters and `limit`.","schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","page","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ListingItem"}},"page":{"$ref":"#/components/schemas/Page"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/listings/{slug}":{"get":{"summary":"Read one listing","operationId":"getListingsBySlug","parameters":[{"name":"slug","in":"path","required":true,"description":"The listing slug.","schema":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"}}],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Listing"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record. `code` is `not_found`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/places":{"get":{"summary":"List countries, regions and cities with counts","operationId":"getPlaces","parameters":[],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PlaceNode"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/categories":{"get":{"summary":"List the category tree with counts","operationId":"getCategories","parameters":[],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CategoryNode"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sources":{"get":{"summary":"List the data sources with license and refresh","operationId":"getSources","parameters":[],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Source"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/stats":{"get":{"summary":"Counts and the last update","operationId":"getStats","parameters":[],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Stats"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches. No body.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"ETag":{"description":"A weak validator. Send it back as `If-None-Match`.","schema":{"type":"string"}},"Cache-Control":{"description":"`public, max-age=60, s-maxage=300, stale-while-revalidate=600`.","schema":{"type":"string"}}}},"400":{"description":"A parameter is unknown, repeated, empty or invalid. `code` is `invalid_parameter` or `invalid_cursor`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the limit of 300 requests per 60 seconds. `code` is `rate_limited`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. 60.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An error on the server. `code` is `internal_error`.","headers":{"RateLimit-Limit":{"description":"Requests allowed per window. 300.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The policy as `limit;w=seconds`. `300;w=60`.","schema":{"type":"string"}},"Access-Control-Allow-Origin":{"description":"`*`. Any origin may read.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"A sentence for a person."},"code":{"type":"string","enum":["invalid_parameter","invalid_cursor","not_found","method_not_allowed","rate_limited","internal_error"],"description":"Stable. Branch on this, not on `error`."},"details":{"description":"One entry per bad parameter, on `invalid_parameter`.","type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"additionalProperties":false}}},"required":["error","code"],"additionalProperties":false},"Meta":{"type":"object","properties":{"attribution":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"},"text":{"type":"string","description":"Credit line to show next to the data."}},"required":["name","url","text"],"additionalProperties":false},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"},"description":"Where the data comes from, with the license of each source."}},"required":["attribution","sources"],"additionalProperties":false},"Source":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"license":{"type":"string","description":"The license of the data taken from this source."},"refresh":{"type":"string","description":"How often the source is re-imported."},"notes":{"type":["string","null"]}},"required":["key","name","url","license","refresh","notes"],"additionalProperties":false},"ListingItem":{"type":"object","properties":{"slug":{"type":"string","description":"The stable identifier. Use it in /listings/{slug}."},"name":{"type":"string"},"path":{"type":"string","description":"The listing page on this site."},"url":{"type":"string","description":"Absolute URL of the listing page."},"country":{"type":"string","description":"ISO 3166-1 alpha-2, upper case."},"region":{"type":"string"},"regionSlug":{"type":"string"},"city":{"type":"string"},"citySlug":{"type":"string"},"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"],"additionalProperties":false},"description":"Primary category first."},"tier":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"completeness":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"0 to 100. How much of the record is filled in."},"attributes":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Public facet attributes, keyed by attribute key."},"indexable":{"type":"boolean","description":"False when the page is kept out of search engines. The record is still public."}},"required":["slug","name","path","url","country","region","regionSlug","city","citySlug","categories","tier","lat","lng","completeness","attributes","indexable"],"additionalProperties":false},"Listing":{"type":"object","properties":{"slug":{"type":"string","description":"The stable identifier. Use it in /listings/{slug}."},"name":{"type":"string"},"path":{"type":"string","description":"The listing page on this site."},"url":{"type":"string","description":"Absolute URL of the listing page."},"country":{"type":"string","description":"ISO 3166-1 alpha-2, upper case."},"region":{"type":"string"},"regionSlug":{"type":"string"},"city":{"type":"string"},"citySlug":{"type":"string"},"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"],"additionalProperties":false},"description":"Primary category first."},"tier":{"type":"string"},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"completeness":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"0 to 100. How much of the record is filled in."},"attributes":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Public facet attributes, keyed by attribute key."},"indexable":{"type":"boolean","description":"False when the page is kept out of search engines. The record is still public."},"description":{"type":["string","null"]},"street":{"type":["string","null"]},"street2":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"phone":{"type":["string","null"]},"website":{"type":["string","null"]},"currency":{"type":"string","description":"ISO 4217."},"language":{"type":"string","description":"BCP 47."},"verified":{"type":"boolean","description":"The listing has an owner or a paid tier."},"source":{"anyOf":[{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"license":{"type":"string"},"refresh":{"type":"string"},"notes":{"description":"The source note: how the record was gathered.","type":["string","null"]},"recordUrl":{"type":"string","description":"Where this record was read."},"retrieved":{"description":"When it was read, ISO 8601.","type":["string","null"]}},"required":["key","name","license","refresh","notes","recordUrl","retrieved"],"additionalProperties":false},{"type":"null"}],"description":"Null for a record that did not come from an import."},"published":{"description":"ISO 8601.","type":["string","null"]},"updated":{"type":"string","description":"ISO 8601."}},"required":["slug","name","path","url","country","region","regionSlug","city","citySlug","categories","tier","lat","lng","completeness","attributes","indexable","description","street","street2","postalCode","phone","website","currency","language","verified","source","published","updated"],"additionalProperties":false},"Page":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Listings that match the filters."},"nextCursor":{"description":"Null on the last page.","type":["string","null"]},"capped":{"type":"boolean","description":"True when more listings match than the cursor can reach. Add a filter or raise `limit`."},"fuzzy":{"type":"boolean","description":"True when nothing matched `q` exactly and the items are close matches."}},"required":["limit","total","nextCursor","capped","fuzzy"],"additionalProperties":false},"PlaceNode":{"type":"object","properties":{"kind":{"type":"string","enum":["country","region","city"]},"name":{"type":"string"},"slug":{"type":"string","description":"Pass a region slug as `region` and a city slug as `city` to /listings."},"country":{"type":"string","description":"ISO 3166-1 alpha-2 code. Pass it as `country` to /listings."},"url":{"type":"string","description":"The page for this place on the site."},"count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Published listings in this place. A place with none is left out."},"children":{"type":"array","items":{"$ref":"#/components/schemas/PlaceNode"},"description":"Regions in a country, cities in a region. Empty for a city."}},"required":["kind","name","slug","country","url","count","children"],"additionalProperties":false},"CategoryNode":{"type":"object","properties":{"slug":{"type":"string","description":"Pass it as `category` to /listings."},"name":{"type":"string"},"url":{"type":"string","description":"The page for this category on the site."},"count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Published listings in this category or one below it. Every category in the config is listed, also with 0."},"children":{"type":"array","items":{"$ref":"#/components/schemas/CategoryNode"}}},"required":["slug","name","url","count","children"],"additionalProperties":false},"Stats":{"type":"object","properties":{"listings":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Published listings."},"countries":{"type":"integer","minimum":0,"maximum":9007199254740991},"regions":{"type":"integer","minimum":0,"maximum":9007199254740991},"cities":{"type":"integer","minimum":0,"maximum":9007199254740991},"categories":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Every category in the tree, at any depth."},"sources":{"type":"integer","minimum":0,"maximum":9007199254740991},"lastUpdated":{"description":"When a published listing last changed. ISO 8601. Null with no listings.","type":["string","null"]}},"required":["listings","countries","regions","cities","categories","sources","lastUpdated"],"additionalProperties":false}}}}