{"revision":"0ed62d2c742f8e20","language":"en","entry":{"id":"logo","kind":"endpoint","group":"share","title":"Read a published logo or photo","method":"GET","path":"/{kind}/{n}/logo.{format}","paths":[],"summary":"Read the image currently published on a person’s or organisation’s card.","response":"The exact published SVG, PNG or GIF when size is omitted. With size=64 or size=128 on a PNG, a smaller display derivative may be returned. Missing or hidden images return 404.","parameters":[{"name":"kind","description":"u or o.","in":"path","required":true},{"name":"n","description":"Permanent positive card number.","in":"path","required":true},{"name":"format","description":"svg, png or gif. Use the card’s logo.url.","in":"path","required":true},{"name":"v","in":"query","required":false,"description":"Current image hash from logo.url. A matching value allows one day of public caching."},{"name":"size","in":"query","required":false,"description":"PNG only, 64 or 128. Request a proportional display thumbnail when it saves bytes. Small PNGs and animated APNGs keep their original bytes. Omit for the exact published image."}],"sample":"/o/2/logo.svg","access":"public","base":"directory","notes":["These image routes use the permanent number. Unpublished preview images have different access requirements.","The response is an image, not JSON. Use it in an img element or read the bytes with response.blob().","Thumbnails are for display. Verify the original image bytes in the signed record. SVG, GIF and APNG animation remain available unchanged; size on SVG/GIF or any value other than 64/128 returns 400 invalid_parameter. Current visibility and the v hash are checked before serving a derivative."],"errors":["400 invalid_parameter","401 invalid_api_key","403 api_key_scope","403 api_key_suspended","403 developer_suspended","404 not_found","410 erased","422 not_a_person","422 not_an_organization","429 rate_limited","500 internal_error","503 busy"],"related":[],"sections":[{"kind":"code","language":"shell","code":"curl -fsS 'https://veil.rip/o/2/logo.svg'"}],"live":false,"responses":[{"status":200,"contentType":"image/svg+xml | image/png | image/gif","description":"The exact published SVG, PNG or GIF when size is omitted. With size=64 or size=128 on a PNG, a smaller display derivative may be returned. Missing or hidden images return 404.","fields":[]}],"responseObjects":[],"errorFormat":"json","errorDetails":[{"status":400,"code":"invalid_parameter","description":"A path, query or body field is missing, malformed or outside its accepted range.","action":"Correct the field named in `error.message` before sending again.","scope":"endpoint"},{"status":401,"code":"invalid_api_key","description":"The bearer credential is malformed, unknown, expired or revoked.","action":"Use an active key. To use anonymous public access, remove `Authorization` entirely. Invalid credentials never fall back automatically.","scope":"optional-api-key"},{"status":403,"code":"api_key_scope","description":"The API key lacks read or verify scope, or the endpoint does not accept bearer keys.","action":"Use the correct scope. Identity writes and key management still require a device signature.","scope":"optional-api-key"},{"status":403,"code":"api_key_suspended","description":"This API key is suspended.","action":"Ask staff to restore it; another key cannot lift an account suspension.","scope":"optional-api-key"},{"status":403,"code":"developer_suspended","description":"The owner’s API account is suspended or the owner card is unavailable.","action":"Check the owner account and any staff restriction. Creating another key does not bypass suspension.","scope":"optional-api-key"},{"status":404,"code":"not_found","description":"The requested card, key, alias, code or resource was not found.","action":"Check the identifier. Temporary codes and previews may already have expired or been used.","scope":"endpoint"},{"status":410,"code":"erased","description":"The card existed and was erased or removed. The response also carries its public erasure receipt.","action":"Stop using this card as current authority. Retain only the public receipt if needed.","scope":"endpoint"},{"status":422,"code":"not_a_person","description":"The card is an organisation where a person is required.","action":"Use the organisation endpoint or an eligible person’s card.","scope":"endpoint"},{"status":422,"code":"not_an_organization","description":"The card is a person where an organisation is required.","action":"Use the person endpoint or an organisation card.","scope":"endpoint"},{"status":429,"code":"rate_limited","description":"An anonymous, signed-request or API-key allowance was exceeded.","action":"Wait at least `Retry-After` seconds. Share a queue and retry budget across your workers.","scope":"common"},{"status":500,"code":"internal_error","description":"An unexpected server error occurred. Internal details are not returned.","action":"Retry reads with bounded backoff. Check write results before sending a new signed operation.","scope":"common"},{"status":503,"code":"busy","description":"The application has reached a temporary concurrency or database limit.","action":"Wait `Retry-After` seconds and retry with bounded backoff.","scope":"common"}],"responseHeaders":[{"name":"Content-Type","value":"image/svg+xml | image/png | image/gif","description":"Use the declared media type before choosing a parser."},{"name":"Date","value":"HTTP date","description":"Server time. Compare it with your clock when signing requests."},{"name":"Cache-Control","value":"no-cache or public, max-age=86400","description":"A v query matching the current hash prefix permits one day of caching."},{"name":"Retry-After","value":"integer seconds, on rate_limited or busy","description":"Wait at least this long before retrying. Other 429/503 codes do not necessarily include it."}],"documentationUrl":"https://veil.rip/docs/logo","supportsBrowserFetch":true,"browserMode":"fetch"}}