{"openapi":"3.1.0","info":{"title":"GrimoirePrint API","version":"1.26.3","summary":"Turn Markdown into a typeset PDF.","description":"Converts Markdown into a designed, print-ready PDF in a choice of themes and document modes. One conversion costs one credit; a failed conversion costs nothing, because the debit happens only once the PDF exists."},"servers":[{"url":"https://grimoireprint.com","description":"Production"}],"security":[{"apiKey":[]}],"paths":{"/api/v1/convert":{"post":{"operationId":"convertMarkdownToPdf","summary":"Convert Markdown to a PDF","description":"Costs one credit on success. Nothing is charged for a rejected request or a failed conversion.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertRequest"}}}},"responses":{"200":{"description":"The PDF was produced and one credit was spent.","headers":{"X-Credits-Remaining":{"description":"Credits left on the account after this request.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per hour for this key and request kind.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix time at which the allowance is fully restored.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertResponse"}}}},"400":{"description":"The request body or an option was malformed. Fix it and retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"The request body or an option was malformed. Fix it and retry.","docs_url":"https://grimoireprint.com/api-docs#invalid_request"}}}}},"401":{"description":"Missing, unknown or revoked API key. Do not retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_key","message":"Missing, unknown or revoked API key. Do not retry.","docs_url":"https://grimoireprint.com/api-docs#invalid_key"}}}}},"402":{"description":"The account behind this key has no credits left.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"The account behind this key has no credits left.","docs_url":"https://grimoireprint.com/api-docs#insufficient_credits"}}}}},"413":{"description":"The markdown exceeds the size limit. Split the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"payload_too_large","message":"The markdown exceeds the size limit. Split the document.","docs_url":"https://grimoireprint.com/api-docs#payload_too_large"}}}}},"429":{"description":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","docs_url":"https://grimoireprint.com/api-docs#rate_limited"}}}}},"500":{"description":"The conversion failed. No credit was spent. Retry once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"conversion_failed","message":"The conversion failed. No credit was spent. Retry once.","docs_url":"https://grimoireprint.com/api-docs#conversion_failed"}}}}},"503":{"description":"The service has no metering database configured and is not accepting API requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"metering_unavailable","message":"The service has no metering database configured and is not accepting API requests.","docs_url":"https://grimoireprint.com/api-docs#metering_unavailable"}}}}}}}},"/api/v1/credits":{"get":{"operationId":"getCredits","summary":"Remaining credits for this key","responses":{"200":{"description":"The balance behind this key.","headers":{"X-Credits-Remaining":{"description":"Credits left on the account after this request.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per hour for this key and request kind.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix time at which the allowance is fully restored.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credits"}}}},"401":{"description":"Missing, unknown or revoked API key. Do not retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_key","message":"Missing, unknown or revoked API key. Do not retry.","docs_url":"https://grimoireprint.com/api-docs#invalid_key"}}}}},"429":{"description":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","docs_url":"https://grimoireprint.com/api-docs#rate_limited"}}}}},"503":{"description":"The service has no metering database configured and is not accepting API requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"metering_unavailable","message":"The service has no metering database configured and is not accepting API requests.","docs_url":"https://grimoireprint.com/api-docs#metering_unavailable"}}}}}}}},"/api/v1/themes":{"get":{"operationId":"listThemes","summary":"Themes, document modes, colour schemes and paper sizes","description":"Call this rather than guessing option values.","responses":{"200":{"description":"Everything a conversion request may ask for.","headers":{"X-Credits-Remaining":{"description":"Credits left on the account after this request.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per hour for this key and request kind.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix time at which the allowance is fully restored.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}},"401":{"description":"Missing, unknown or revoked API key. Do not retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_key","message":"Missing, unknown or revoked API key. Do not retry.","docs_url":"https://grimoireprint.com/api-docs#invalid_key"}}}}},"429":{"description":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"Per-key rate limit or concurrency limit reached. Retry after the Retry-After header.","docs_url":"https://grimoireprint.com/api-docs#rate_limited"}}}}},"503":{"description":"The service has no metering database configured and is not accepting API requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"metering_unavailable","message":"The service has no metering database configured and is not accepting API requests.","docs_url":"https://grimoireprint.com/api-docs#metering_unavailable"}}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApiDocument","summary":"This document","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 description of this API.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key, sent as `Authorization: Bearer mdp_sk_…`."}},"schemas":{"ConvertRequest":{"type":"object","required":["markdown"],"properties":{"markdown":{"type":"string","description":"The Markdown document to typeset. Up to 2 MB."},"theme":{"type":"string","enum":["default","fantasy"],"default":"default","description":"default: Clean editorial typesetting for documents, reports and newsletters. fantasy: Tabletop sourcebook styling — parchment, stat blocks, callouts and drop caps"},"mode":{"type":"string","enum":["standard","newsletter","poem","newspaper-times","newspaper-tabloid","resume","certificate","report"],"default":"standard","description":"standard: Clean, minimal document. newsletter: Modern email-newsletter layout. poem: Centred verse with elegant serif typography. newspaper-times: Classic multi-column broadsheet. newspaper-tabloid: Bold, punchy red-top layout. resume: Clean, ATS-friendly CV layout. certificate: Centred, landscape award layout. report: Cover page, table of contents, headers and footers"},"paper":{"type":"string","enum":["A4","Letter","Legal","Tabloid"],"default":"A4"},"columns":{"type":"string","enum":["1","2"],"description":"Defaults to 2 for the fantasy theme and 1 otherwise."},"colors":{"type":"string","enum":["classic","ocean","forest","infernal","arcane","greyscale"],"default":"classic","description":"Colour scheme. Applies to the fantasy theme only."},"dropCapStyle":{"type":"string","enum":["none","simple","gothic","celtic","gilded","blackletter","uncial","regal","woodcut","illuminated","royal-blue-gold","verdant-knotwork","gold-filigree","pen-ink","potato-print","goblin","ember","arcane","frost","verdant","obsidian","celestial","blood-ink","copper","moonstone","engraved","infernal","runic","sylvan"],"description":"Decorative first letter. Applies to the fantasy theme only."},"output":{"type":"string","enum":["url","base64"],"default":"url","description":"url returns a short-lived download link (preferred). base64 returns the whole PDF inline, which is expensive — a few megabytes of base64 in a model context is rarely what you want."},"config":{"type":"object","additionalProperties":true,"description":"Advanced typography and layout overrides."}}},"ConvertResponse":{"type":"object","required":["filename","bytes","credits_remaining"],"properties":{"download_url":{"type":"string","description":"Short-lived link to the PDF. Present when output is \"url\"."},"expires_in":{"type":"integer","description":"Seconds the download link remains valid."},"pdf_base64":{"type":"string","description":"The PDF itself. Present only when output is \"base64\"."},"filename":{"type":"string"},"bytes":{"type":"integer"},"credits_remaining":{"type":"integer"},"theme":{"type":"string"},"mode":{"type":"string"}}},"Credits":{"type":"object","required":["credits","free_remaining","free_eligible"],"properties":{"credits":{"type":"integer","description":"Purchased credits remaining."},"free_remaining":{"type":"integer","description":"Always 0 for API keys: the free monthly allowance is for browser use."},"free_eligible":{"type":"boolean"},"key":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":["string","null"]}}}}},"Catalog":{"type":"object","properties":{"themes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEntry"}},"modes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEntry"}},"colors":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEntry"}},"paper_sizes":{"type":"array","items":{"type":"object"}},"columns":{"type":"array","items":{"type":"string"}},"drop_cap_styles":{"type":"array","items":{"type":"string"}},"output":{"type":"array","items":{"type":"string"}}}},"CatalogEntry":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","docs_url"],"properties":{"code":{"type":"string","enum":["invalid_request","invalid_key","insufficient_credits","not_found","method_not_allowed","payload_too_large","rate_limited","conversion_failed","metering_unavailable"]},"message":{"type":"string"},"docs_url":{"type":"string"}}}}}}}}