{"openapi":"3.1.0","info":{"title":"Printaloo API","version":"1","description":"Printaloo connects a company's printers to its apps. An app sends a PDF, ZPL or PNG, and it prints on the right printer,\nonce, with an honest state for every page.\n\nOnly https: a request over plain http gets `403 https_required`, never a redirect. A key sent over http has\ncrossed the network unencrypted, so replace it.\n\nErrors are RFC 9457 problem details (application/problem+json) with a stable `code`.\nSend `Accept-Language: el` for Greek words, or `en` for English (the default)."},"servers":[{"url":"https://api.printaloo.com"}],"tags":[{"name":"API keys"},{"name":"Accounts"},{"name":"Computers"},{"name":"Members"},{"name":"People"},{"name":"Places"},{"name":"Print jobs"},{"name":"Printers"},{"name":"Program"},{"name":"Sessions"},{"name":"System"},{"name":"Webhooks"}],"paths":{"/v1/account":{"get":{"operationId":"getAccount","summary":"The account of the request","description":"For an API key, the account the key belongs to.","tags":["Accounts"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateAccount","summary":"Change the account's name, language, time zone or file retention, or make a personal account a company's","description":"A personal account becomes a company's with `kind: company`, by its Owner, with all it has. Never back.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"kind":{"description":"company: a personal account becomes a company's, with all it has, and may have members. Only its Owner; never back.","$ref":"#/components/schemas/AccountKind"},"locale":{"$ref":"#/components/schemas/Locale"},"file_retention":{"$ref":"#/components/schemas/FileRetention"},"time_zone":{"type":"string","minLength":1,"maxLength":64}},"additionalProperties":false}}}},"responses":{"200":{"description":"The account, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_kind_fixed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/data-export":{"get":{"operationId":"getDataExport","summary":"Your ZIP of the account's data: how far it got, or that it is ready","description":"Each Owner and Admin has their own. Ask it again every few seconds while it is being prepared.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Status none when there is none.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataExport"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"startDataExport","summary":"Ask for a ZIP of the account's data","description":"The jobs and the audit log in CSV, and the files we keep, as you see them. It is prepared in the background, and stays 7 days once ready. A new one replaces yours; while yours is being prepared, you get that one. Also while the account is being deleted.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"202":{"description":"Being prepared.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataExport"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/data-export/link":{"post":{"operationId":"createDataExportLink","summary":"A link that downloads your ZIP, for an hour","description":"A browser downloads from it without the Authorization header, and resumes there if the download breaks. A new link replaces the last one. Each one is written to the audit log.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Open it, or give it to the browser.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataExportLink"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, data_export_not_ready.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/data-export/preview":{"get":{"operationId":"previewDataExport","summary":"What a ZIP of the account's data would hold now","description":"The jobs and the files you see: those of another person's home are never in yours (S05).","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Counted now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataExportContents"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/data-export/seen":{"post":{"operationId":"markDataExportSeen","summary":"Say you saw that your ZIP is ready, or failed","description":"The app tells you until then, in the bell and once on any page. Asking for a link says it too.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"With seen_at.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataExport"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/delete":{"post":{"operationId":"deleteAccount","summary":"Delete the account: everything goes in 30 days","description":"Only the Owner, with the account's name as confirmation. At once, every computer is removed and its program says «Ο λογαριασμός διαγράφηκε», and every API key and invitation stops working. The data stays 30 days: the Owner can still read it, or restore the account. Then the files, the jobs and everything else are deleted for good; only the line of the audit log that says so stays.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_name":{"type":"string","minLength":1,"maxLength":120,"description":"The account's name, typed by the Owner: deleting cannot be undone after 30 days."}},"required":["confirm_name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The account, with the day its data goes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/file-retention/preview":{"get":{"operationId":"previewFileRetention","summary":"What a new file retention would delete now","description":"Before «Αποθήκευση» (S03b): the files a choice deletes at once if saved, and the jobs whose files they are. Those jobs stay in the list, without their preview and «Τύπωσε ξανά». A file that a job still waits for is never deleted.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"mode","in":"query","required":true,"schema":{"type":"string","enum":["keep","after_print","days"]}},{"name":"days","in":"query","required":false,"description":"With mode days: how many.","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"What it deletes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileRetentionPreview"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/leave":{"post":{"operationId":"leaveAccount","summary":"Leave the account","description":"The person stops being a member at once. The Owner must first make another member the Owner.","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The person is no longer a member."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, owner_cannot_leave.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/restore":{"post":{"operationId":"restoreAccount","summary":"Take back an account being deleted","description":"Only the Owner, before its data goes. Everything in it comes back, except its computers and API keys, which stopped for good: pair the computers again, and make new keys.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The account, as before.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_not_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/transfer-ownership":{"post":{"operationId":"transferOwnership","summary":"Make another member the Owner","description":"Only the Owner can. The old Owner becomes an Admin.","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"person_id":{"type":"string","pattern":"^usr_[0-9a-z]{26}$","description":"A member who becomes the Owner."}},"required":["person_id"],"additionalProperties":false}}}},"responses":{"204":{"description":"The member is the Owner, and the old Owner is an Admin."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts":{"post":{"operationId":"createAccount","summary":"Make a new account, with the signed-in person as its Owner","description":"Its name is enough, also for a person's second account (PRODUCT §4.1). A person makes up to 10 an hour. Only a server that takes new accounts by invitation, such as a staging, also wants `signup_code`. With an Idempotency-Key, a request whose answer was lost can come again for a day: the same key with the same details answers 200 with the account it made, and counts once against the 10; with other details, 409.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Your own id for this request: a new one for each thing you ask for, e.g. the id of the print in your system. The same request sent again with the same key makes nothing new: it answers with what the first one made.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"The name of the company, or of the person."},"kind":{"default":"company","description":"A company's by default; personal: for one person alone, without members.","$ref":"#/components/schemas/AccountKind"},"signup_code":{"description":"Only on a server that takes new accounts by invitation, such as a staging: the invitation from Printaloo.","type":"string","minLength":1,"maxLength":200},"time_zone":{"description":"The browser's own, from Intl.DateTimeFormat().resolvedOptions().timeZone. Without it, Europe/Athens.","type":"string","minLength":1,"maxLength":64},"locale":{"description":"The browser's own language, from navigator.language. Without it, the person's.","$ref":"#/components/schemas/Locale"}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The account that this Idempotency-Key made before (Idempotent-Replayed: true).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"201":{"description":"The new account. The person who made it is its Owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required, signup_invitation_invalid, signup_invitation_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_key_conflict, account_key_used.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent-releases/{version}/installer":{"get":{"operationId":"downloadAgentInstaller","summary":"Download the installer of a release","description":"One range of bytes resumes a download that broke (Range, If-Range with the ETag). A release that was taken back no longer downloads.","tags":["Program"],"security":[],"parameters":[{"name":"version","in":"path","required":true,"schema":{"type":"string","pattern":"^(0|[1-9][0-9]{0,3})\\.(0|[1-9][0-9]{0,3})\\.(0|[1-9][0-9]{0,3})$"}}],"responses":{"200":{"description":"The installer.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"206":{"description":"The range asked for.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"416":{"description":"Problem: range_not_satisfiable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent-releases/latest":{"get":{"operationId":"getLatestAgentRelease","summary":"The newest release of the Printaloo program for Windows","description":"For the site's «Κατέβασε το Printaloo», and for whoever installs the program on many computers.","tags":["Program"],"security":[],"responses":{"200":{"description":"The newest release that was not taken back.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRelease"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent-releases/latest/installer":{"get":{"operationId":"downloadLatestAgentInstaller","summary":"Download the newest installer","description":"A link that stays the same: it sends to the installer of the newest release.","tags":["Program"],"security":[],"responses":{"302":{"description":"To the installer of the newest release."},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/claims":{"post":{"operationId":"claimJobs","summary":"Take the next job of each printer that can print now","description":"Call it when the program connects, after jobs.available, and after a printer is ready again. The first job of each printer, one at a time: write it in the journal before sending it to the printer, so that a restart never prints it twice.","tags":["Program"],"security":[{"computer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printer_ids":{"description":"The printers it can print to now. Leave out one that says it is offline: its jobs wait, and expire cleanly.","maxItems":500,"type":"array","items":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}}},"additionalProperties":false}}}},"responses":{"200":{"description":"The jobs it took, at most one per printer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimedJobList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/computer":{"get":{"operationId":"getAgentComputer","summary":"Where this computer is: its account, location and workstation","tags":["Program"],"security":[{"computer":[]}],"responses":{"200":{"description":"As the program's window shows it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairedComputer"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/connect":{"get":{"operationId":"connectAgent","summary":"Open the computer's WebSocket","description":"Outbound only, on port 443. The server says when there are jobs, when the computer's place changes, when it was removed, and when a new release of the program is out. The program sends {\"type\":\"ping\"} every 30 seconds and gets {\"type\":\"pong\"}. Its User-Agent, «Printaloo/1.4.0», says its version, which the app shows.","tags":["Program"],"security":[{"computer":[]}],"responses":{"101":{"description":"The WebSocket is open."},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/files/{id}":{"get":{"operationId":"getAgentFile","summary":"Download the file of a job this computer holds","description":"Only while its job is claimed or spooled by this computer. The program deletes it as soon as it printed.","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^fil_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The file, as the app sent it.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: file_gone.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/found-printers":{"post":{"operationId":"reportFoundPrinters","summary":"Report printers seen on the network","description":"What the program saw without a driver (docs/api/AGENT.md §8): in its own searches, and in one the server asked for with printers.search, as it comes, then once more with done. A printer seen again only says it is still there.","tags":["Program"],"security":[{"computer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"search_id":{"description":"The search the server asked for; without it, a search of the program's own.","type":"string","pattern":"^srh_[0-9a-z]{26}$"},"found":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":512,"description":"The same device, whichever computer sees it: its IPP uuid, else its mDNS name, else its address."},"name":{"type":"string","minLength":1,"maxLength":255},"make":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"model":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"kind":{"anyOf":[{"$ref":"#/components/schemas/PrinterKind"},{"type":"null"}]},"color":{"type":["boolean","null"]},"paper":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"description":"The size it is set to, e.g. A4, when it says."},"uri":{"type":"string","maxLength":512,"pattern":"^(ipps?|socket):\\/\\/[^\\s/?#]+(\\/[^\\s?#]*)?$"},"address":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"printer_ref":{"anyOf":[{"type":"string","minLength":1,"maxLength":512},{"type":"null"}],"description":"The ref of a printer this computer already has for this device, e.g. the same printer in its Windows."}},"required":["key","name","make","model","kind","color","paper","uri","address","printer_ref"],"additionalProperties":false},"description":"What it saw since the last report of this search."},"done":{"default":false,"description":"With search_id: it searched as long as it was asked.","type":"boolean"}},"required":["found"],"additionalProperties":false}}}},"responses":{"204":{"description":"Taken."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/jobs":{"get":{"operationId":"listAgentJobs","summary":"The latest jobs of this computer's printers, for the program's window","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":30,"type":"integer","minimum":1,"maximum":100}},{"name":"day","in":"query","required":false,"description":"Only today's, where the account is, with how many they are in total («148 σήμερα»).","schema":{"type":"string","const":"today"}}],"responses":{"200":{"description":"The newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/jobs/{id}/cancel":{"post":{"operationId":"cancelAgentJob","summary":"Cancel a job of this computer's printers, from the program's window","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: job_not_cancellable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/jobs/{id}/confirm":{"post":{"operationId":"confirmAgentJob","summary":"Say whether a job came out right, from the program's window","description":"The person at the computer says it: «Βγήκε σωστά» or «Δεν βγήκε σωστά».","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["ok","not_ok"],"description":"ok: it came out right. not_ok: it did not."}},"required":["outcome"],"additionalProperties":false}}}},"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: job_decided, job_not_confirmable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/jobs/{id}/reprint":{"post":{"operationId":"reprintAgentJob","summary":"Print a job again, from the program's window","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Your own id for this request: a new one for each thing you ask for, e.g. the id of the print in your system. The same request sent again with the same key makes nothing new: it answers with what the first one made.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printer_id":{"description":"Another printer that fits; the same printer when left out.","type":"string","pattern":"^prn_[0-9a-z]{26}$"},"from_page":{"description":"From this page of a PDF, or this label of a ZPL file.","type":"integer","minimum":1}},"additionalProperties":false}}}},"responses":{"200":{"description":"The job this Idempotency-Key made before.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"201":{"description":"The new job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Problem: plan_limit_reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: idempotency_conflict, idempotency_key_used.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: file_gone.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: file_invalid, page_out_of_range, size_mismatch, size_unsupported, unsupported_option, zpl_dpi_mismatch, zpl_unsupported.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/journal":{"post":{"operationId":"reportJobs","summary":"Say what happened to the jobs this computer holds","description":"Each entry is a step of one job, with the claim it came with: spooled, printed, failed, expired, cancelled, or queued when the program left the job before sending it. holding: the claimed jobs still in hand, whose claim lives another 120 seconds; the program says it every 30 seconds. With complete, after a restart: a claimed job that is in neither was never sent to the printer, and goes back to its queue. The answer says which jobs a person cancelled while the computer held them.","tags":["Program"],"security":[{"computer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"maxItems":1000,"type":"array","items":{"$ref":"#/components/schemas/JournalEntry"}},"complete":{"default":false,"description":"Every job the computer still holds is in entries or holding, as after a restart: a claimed job that is not there was never sent to the printer, and goes back to its queue.","type":"boolean"},"holding":{"default":[],"description":"Claimed jobs the computer still has in hand, before the printer's queue has all of them: downloading, or being sent. Each claim lives another 120 seconds, so a long job never reads as its computer gone silent.","maxItems":1000,"type":"array","items":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"claim_id":{"type":"string","pattern":"^clm_[0-9a-z]{26}$"}},"required":["job_id","claim_id"],"additionalProperties":false}}},"required":["entries"],"additionalProperties":false}}}},"responses":{"200":{"description":"What became of each entry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalResult"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/pairings":{"post":{"operationId":"startPairing","summary":"Ask to join an account: the program gets a code to show","description":"The program sends its own Ed25519 public key and signs the request with the private key (Authorization: PrintalooAgent id=\"new\", …). It shows the code and the QR of approve_url, and asks GET /v1/agent/pairings/{id} until a person approves it in the app. A code lasts 10 minutes; then the program asks for a new one.","tags":["Program"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"public_key":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$","description":"The computer's own Ed25519 public key. The request is signed with its private key."},"computer_name":{"type":"string","minLength":1,"maxLength":120},"os":{"type":"string","maxLength":120},"agent_version":{"type":"string","maxLength":40}},"required":["public_key","computer_name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The code to show, until it expires.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairingStarted"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/pairings/{id}":{"get":{"operationId":"getPairingState","summary":"Whether a person approved the pairing yet","description":"Signed with the key of the pairing (id=\"pai_…\"). Once approved, the program connects as its computer.","tags":["Program"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Waiting, approved (with where the computer is), denied, or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairingState"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/printer-probes/{id}":{"post":{"operationId":"reportPrinterProbe","summary":"Answer a test of an address","description":"What the program found at the address it was asked with printers.probe (docs/api/AGENT.md §8). Only the first answer counts.","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prb_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"string","enum":["found","no_answer","not_a_printer"]},"printer":{"anyOf":[{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":512,"description":"The same device, whichever computer sees it: its IPP uuid, else its mDNS name, else its address."},"name":{"type":"string","minLength":1,"maxLength":255},"make":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"model":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"kind":{"anyOf":[{"$ref":"#/components/schemas/PrinterKind"},{"type":"null"}]},"color":{"type":["boolean","null"]},"paper":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"description":"The size it is set to, e.g. A4, when it says."},"uri":{"type":"string","maxLength":512,"pattern":"^(ipps?|socket):\\/\\/[^\\s/?#]+(\\/[^\\s?#]*)?$"},"address":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"printer_ref":{"anyOf":[{"type":"string","minLength":1,"maxLength":512},{"type":"null"}],"description":"The ref of a printer this computer already has for this device, e.g. the same printer in its Windows."}},"required":["key","name","make","model","kind","color","paper","uri","address","printer_ref"],"additionalProperties":false},{"type":"null"}],"description":"With found: the printer that answered."},"detail":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"What it saw, in its own words."}},"required":["result","printer","detail"],"additionalProperties":false}}}},"responses":{"204":{"description":"Taken."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/printers":{"put":{"operationId":"reportPrinters","summary":"Report every printer the program has now","description":"The whole list each time: when the program starts, when it connects, and whenever something changes (docs/api/AGENT.md §5). One report at a time. The answer gives the id of each printer: the program keeps its own data by that id, and sends it with the printer from then on. A printer the report leaves out is «not found».","tags":["Program"],"security":[{"computer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printers":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"id":{"description":"The id the server gave it, once the program knows it.","type":"string","pattern":"^prn_[0-9a-z]{26}$"},"ref":{"type":"string","minLength":1,"maxLength":512,"description":"The program's handle for it on this computer: the Windows name, or the address of a printer it reaches without a driver."},"name":{"type":"string","minLength":1,"maxLength":255,"description":"What Windows, or the printer, calls it."},"connection":{"type":"string","enum":["usb","network","shared","direct","software","other"]},"make":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"model":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"driver":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}]},"port":{"description":"Its port, as Windows calls it: USB001, IP_192.168.1.40, WSD-…. A program from before it sends none.","anyOf":[{"type":"string","maxLength":255},{"type":"null"}]},"capabilities":{"type":"object","properties":{"papers":{"anyOf":[{"maxItems":500,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"width_mm":{"type":"number","exclusiveMinimum":0,"maximum":2000},"height_mm":{"type":"number","exclusiveMinimum":0,"maximum":20000}},"required":["name","width_mm","height_mm"],"additionalProperties":false}},{"type":"null"}]},"dpi":{"anyOf":[{"maxItems":20,"type":"array","items":{"type":"integer","minimum":50,"maximum":4800}},{"type":"null"}]},"zpl":{"type":["boolean","null"]},"duplex":{"anyOf":[{"maxItems":3,"type":"array","items":{"$ref":"#/components/schemas/Duplex"}},{"type":"null"}]},"color":{"anyOf":[{"maxItems":2,"type":"array","items":{"$ref":"#/components/schemas/ColorMode"}},{"type":"null"}]},"trays":{"anyOf":[{"maxItems":50,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64},"name":{"type":"string","minLength":1,"maxLength":120}},"required":["id","name"],"additionalProperties":false}},{"type":"null"}]},"darkness":{"anyOf":[{"maxItems":201,"type":"array","items":{"type":"number","minimum":-100,"maximum":100}},{"type":"null"}]},"speed_ips":{"anyOf":[{"maxItems":100,"type":"array","items":{"type":"number","exclusiveMinimum":0,"maximum":100}},{"type":"null"}]}},"required":["papers","dpi","zpl","duplex","color","trays","darkness","speed_ips"],"additionalProperties":false},"defaults":{"type":"object","properties":{"paper":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"width_mm":{"type":"number","exclusiveMinimum":0,"maximum":2000},"height_mm":{"type":"number","exclusiveMinimum":0,"maximum":20000}},"required":["name","width_mm","height_mm"],"additionalProperties":false},{"type":"null"}],"description":"The size its driver is set to."},"duplex":{"anyOf":[{"$ref":"#/components/schemas/Duplex"},{"type":"null"}]},"color":{"anyOf":[{"$ref":"#/components/schemas/ColorMode"},{"type":"null"}]},"tray":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]},"darkness":{"anyOf":[{"type":"number","minimum":-100,"maximum":100},{"type":"null"}]},"speed_ips":{"anyOf":[{"type":"number","exclusiveMinimum":0,"maximum":100},{"type":"null"}]}},"required":["paper","duplex","color","tray","darkness","speed_ips"],"additionalProperties":false,"description":"How the printer itself is set up: what a job gets when it does not ask."},"status":{"type":"string","enum":["ready","offline","error"]},"problem":{"anyOf":[{"$ref":"#/components/schemas/PrinterProblem"},{"type":"null"}],"description":"With status error: what is wrong."},"detail":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"The printer's own words, e.g. «Media Out»."}},"required":["ref","name","connection","make","model","driver","capabilities","defaults","status","problem","detail"],"additionalProperties":false},"description":"Every printer the program has now. One that is missing is «not found»."}},"required":["printers"],"additionalProperties":false}}}},"responses":{"200":{"description":"The computer's printers, by the ids the server gave them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPrinterList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/printers/{id}/pause":{"post":{"operationId":"pauseAgentPrinter","summary":"Pause a printer from the program's window","description":"«Παύση εκτυπωτή» is in the app and in the program (PRODUCT §4.3). Only a printer of this computer.","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The computer's printers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPrinterList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/printers/{id}/resume":{"post":{"operationId":"resumeAgentPrinter","summary":"Let a printer go on, from the program's window","description":"«Παύση εκτυπωτή» is in the app and in the program (PRODUCT §4.3). Only a printer of this computer.","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The computer's printers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentPrinterList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/agent/printers/{id}/test-page":{"post":{"operationId":"printAgentTestPage","summary":"Print a test page, from the program's window","description":"Only on a printer of this computer.","tags":["Program"],"security":[{"computer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"description":"pdf when left out: a page on the printer's own size, a label's too. zpl: a ZPL label as it is, which tries the ZPL path of a label printer that takes ZPL.","type":"string","enum":["pdf","zpl"]}},"additionalProperties":false}}}},"responses":{"201":{"description":"The job of the test page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: size_unsupported, zpl_unsupported.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys":{"get":{"operationId":"listApiKeys","summary":"The account's API keys","description":"Every key that can still work or come back, newest first: one for each app. A key replaced by a rotation, while its grace lasts, is the `previous` of its new key, not a row of its own.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The keys, without their secrets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createApiKey","summary":"Make an API key","description":"A name, what it allows, which printers, and when it expires. The secret is shown only in this answer.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"scopes":{"minItems":1,"maxItems":4,"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"printer_access":{"default":"all","description":"all: every printer of the account, now and later.","type":"string","enum":["all","selected"]},"printer_ids":{"maxItems":500,"type":"array","items":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},"expires_at":{"description":"No date: the key does not expire.","anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["name","scopes"],"additionalProperties":false}}}},"responses":{"201":{"description":"The key, with its secret shown only now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys/{id}":{"get":{"operationId":"getApiKey","summary":"One API key","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The key, without its secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateApiKey","summary":"Change a key's name, what it allows, its printers or its expiry","description":"The change applies to the next request that uses the key. A stopped key takes changes too: they apply once it is resumed. «Παράτεινε» is a new expires_at, also for a key that expired: it works again, with the same secret. A key that a new secret replaced takes none.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"scopes":{"minItems":1,"maxItems":4,"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"printer_access":{"type":"string","enum":["all","selected"]},"printer_ids":{"maxItems":500,"type":"array","items":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The key, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, key_not_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys/{id}/resume":{"post":{"operationId":"resumeApiKey","summary":"Resume a stopped key","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The key, working again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, key_not_restorable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys/{id}/revoke":{"post":{"operationId":"revokeApiKey","summary":"Cut a key for good","description":"«Leaked» and «not needed» both cut the key at once and for ever, without undo and without grace.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"default":"not_needed","description":"leaked: it was seen where it should not be.","type":"string","enum":["leaked","not_needed"]}},"additionalProperties":false}}}},"responses":{"204":{"description":"The key never works again."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys/{id}/rotate":{"post":{"operationId":"rotateApiKey","summary":"Give a key a new secret","description":"A new key takes the place of the old one, with the same name, permissions and printers. The old key stops at once, unless a grace is asked for (1 hour, 24 hours or 7 days). «Διέρρευσε», when the app still needs the key: reason leaked, and the old key stops at once.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"grace":{"default":"none","description":"How long the old key keeps working: none by default, so a rotation cuts the old key at once.","type":"string","enum":["none","1h","24h","7d"]},"reason":{"default":"routine","description":"leaked: «Διέρρευσε», and the app still needs the key: the old secret stops at once (grace none), and the audit log says it leaked.","type":"string","enum":["routine","leaked"]}},"additionalProperties":false}}}},"responses":{"201":{"description":"The new key, with its secret shown only now, and the old one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotatedApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, key_not_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/api-keys/{id}/stop":{"post":{"operationId":"stopApiKey","summary":"Stop a key, so that it can be resumed within 30 days","description":"The key stops working at once. It can be resumed for 30 days; after that it never works again.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The key, stopped.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/apps":{"get":{"operationId":"listApps","summary":"The apps that print for the account","description":"Each API key with the keys that replaced it, named as its newest key, for the «Εφαρμογή» of the jobs: their app.id, and the list's app_id. Whoever sees the jobs sees them.","tags":["API keys"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The apps, by name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/audit-event-views":{"get":{"operationId":"listAuditEventViews","summary":"The views a person keeps of the audit log","description":"Only theirs, in this account, by name.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The views.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventViewList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createAuditEventView","summary":"Keep a view of the audit log","description":"«Αποθήκευση προβολής»: the list's filters and order, by a name of the person's choosing.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"filters":{"type":"object","properties":{"q":{"description":"Words in the name of what changed, or of who changed it. Not in the details of a line.","type":"string","minLength":1,"maxLength":100},"actor_id":{"description":"Only what these did: people, keys or computers, separated by commas.","type":"string"},"subject":{"description":"Only these kinds of lines, separated by commas.","type":"string"},"target_id":{"description":"Only the lines about this key, computer, person or printer.","type":"string","pattern":"^[a-z]{3}_[0-9a-z]{26}$"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"from":{"description":"From this moment on.","type":"string","format":"date-time"},"to":{"description":"Before this moment.","type":"string","format":"date-time"},"sort":{"$ref":"#/components/schemas/AuditSort"}},"additionalProperties":false}},"required":["name","filters"],"additionalProperties":false}}}},"responses":{"201":{"description":"The view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventView"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken, too_many_views.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/audit-event-views/{id}":{"patch":{"operationId":"updateAuditEventView","summary":"Rename a view of the audit log, or keep other filters in it","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"filters":{"type":"object","properties":{"q":{"description":"Words in the name of what changed, or of who changed it. Not in the details of a line.","type":"string","minLength":1,"maxLength":100},"actor_id":{"description":"Only what these did: people, keys or computers, separated by commas.","type":"string"},"subject":{"description":"Only these kinds of lines, separated by commas.","type":"string"},"target_id":{"description":"Only the lines about this key, computer, person or printer.","type":"string","pattern":"^[a-z]{3}_[0-9a-z]{26}$"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"from":{"description":"From this moment on.","type":"string","format":"date-time"},"to":{"description":"Before this moment.","type":"string","format":"date-time"},"sort":{"$ref":"#/components/schemas/AuditSort"}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"The view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventView"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteAuditEventView","summary":"Delete a view of the audit log","description":"Only the view: the log stays as it is.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The view is gone."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/audit-events":{"get":{"operationId":"listAuditEvents","summary":"Who changed access in the account, newest first","description":"Keys, members, invitations, computers, and moves between locations, which change who prints where (PRODUCT §4.3). Each line stays one year. Search finds words in the name of what changed and of who changed it. A page starts after a `cursor`, the newest first, or after an `offset`, in any order and with the `total` («1–20 από 85»).","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Words in the name of what changed, or of who changed it. Not in the details of a line.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"actor_id","in":"query","required":false,"description":"Only what these did: people, keys or computers, separated by commas.","schema":{"type":"string"}},{"name":"subject","in":"query","required":false,"description":"Only these kinds of lines, separated by commas.","schema":{"type":"string"}},{"name":"target_id","in":"query","required":false,"description":"Only the lines about this key, computer, person or printer.","schema":{"type":"string","pattern":"^[a-z]{3}_[0-9a-z]{26}$"}},{"name":"day","in":"query","required":false,"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","schema":{"anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]}},{"name":"from","in":"query","required":false,"description":"From this moment on.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Before this moment.","schema":{"type":"string","format":"date-time"}},{"name":"sort","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AuditSort"}},{"name":"cursor","in":"query","required":false,"description":"The next_cursor of the previous page: the newest first, without offset.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,200}$"}},{"name":"offset","in":"query","required":false,"description":"Skip this many lines; the page says the total.","schema":{"type":"integer","minimum":0,"maximum":1000000}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"A page of the log.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/computers":{"get":{"operationId":"listComputers","summary":"The account's computers","description":"The computers with the Printaloo program, by place, and whether each is online.","tags":["Computers"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Every computer that is part of the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/computers/{id}":{"get":{"operationId":"getComputer","summary":"One computer","tags":["Computers"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The computer's id.","schema":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The computer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Computer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"removeComputer","summary":"Remove a computer from the account","description":"«Αφαίρεση υπολογιστή»: its access ends at once, and its program says it was removed. Its printers stay, «not found», until a person says which printer each is now, or removes it: so that apps and keys keep their ids.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The computer's id.","schema":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The computer is no longer part of the account."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/computers/{id}/placement":{"put":{"operationId":"placeComputer","summary":"Say where a computer is: its location and workstation","description":"An existing location or workstation by id, or a new one by name. A workstation chosen by id brings its location. With only a location, the computer's own workstation moves with it. The workstation its pairing made is removed when it is left empty. Its program is told at once.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The computer's id.","schema":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"required":["name"],"additionalProperties":false}]},"workstation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"required":["name"],"additionalProperties":false}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The computer, in its new place.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Computer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/computers/{id}/replace":{"post":{"operationId":"replaceComputer","summary":"This computer takes the place of an old one","description":"For a computer that changed or was set up again (PRODUCT §4.2): it moves to the old one's workstation, and the old one leaves the account at once. The old one's printers come with their ids, defaults and permissions: one with the same Windows name on this computer is the same printer, and any other is «not found» until a person says which printer it is now.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The computer's id.","schema":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"computer_id":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$","description":"The old computer: this one takes its place, and the old one leaves the account."}},"required":["computer_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The computer, in the old one's place.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Computer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/data-export-downloads/{token}":{"get":{"operationId":"downloadDataExport","summary":"Download a ZIP of an account's data, from its link","description":"The link is the permission, for an hour: as the app, it works for the person who asked while they are its Owner or an Admin, and only for the Owner while the account is being deleted. One range of bytes resumes a download (Range, If-Range with the ETag).","tags":["Accounts"],"security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","pattern":"^pld_[0-9A-Za-z]{43}$"}}],"responses":{"200":{"description":"The ZIP.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"206":{"description":"The range asked for.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: data_export_link_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"416":{"description":"Problem: range_not_satisfiable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/found-printers":{"get":{"operationId":"listFoundPrinters","summary":"Printers the computers see on the network, that are not the account's printers yet","description":"«Βρέθηκαν στο δίκτυο»: what a computer saw in the last day, by name. Each comes in only when a person adds it, with POST /v1/found-printers/{id}/add.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The found printers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FoundPrinterList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/found-printers/{id}/add":{"post":{"operationId":"addFoundPrinter","summary":"Add a found printer: «Πρόσθεσε»","description":"It becomes a printer of a computer that sees it, which prints to it without a driver (connection direct), at that computer's place until a person places it. A found printer that is a printer of the account already answers 200 with that printer.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^fnd_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"computer_id":{"description":"The computer that prints to it: by default the one that saw it last.","type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},"additionalProperties":false}}}},"responses":{"200":{"description":"The printer it is already.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"201":{"description":"The new printer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, found_printer_unseen.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/health":{"get":{"operationId":"getHealth","summary":"Check that the API answers and reaches its database","tags":["System"],"security":[],"responses":{"200":{"description":"The API works and reaches its database.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"403":{"description":"Problem: https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/invitations":{"post":{"operationId":"createInvitation","summary":"Invite a person to the account","description":"Until there is a way to send email, the invitation is a link to copy. It works once, for 7 days. With an email, only a person signed in with that email can accept it.","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"default":"operator","description":"operator by default: the least a person needs.","type":"string","enum":["admin","operator"]},"email":{"description":"Whom it is meant for, by email: then only a person signed in with this email can accept it.","type":"string","maxLength":320},"name":{"description":"Whom it is meant for, by name, when the person who invites writes no email; only shown in the list.","type":"string","minLength":1,"maxLength":120}},"additionalProperties":false}}}},"responses":{"201":{"description":"The invitation, and its token, shown only now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedInvitation"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listInvitations","summary":"The invitations that can still be used, and those that expired in the last 30 days","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/invitations/{id}":{"delete":{"operationId":"revokeInvitation","summary":"Cancel an invitation, or delete one that expired","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^inv_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The link no longer works."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/invitations/accept":{"post":{"operationId":"acceptInvitation","summary":"Join the account of an invitation","tags":["Members"],"security":[{"session":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":10,"maxLength":200}},"required":["token"],"additionalProperties":false}}}},"responses":{"200":{"description":"The person is a member, with the role of the invitation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountMembership"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required, invitation_other_email.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: invitation_invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: already_member.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: invitation_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/invitations/preview":{"post":{"operationId":"previewInvitation","summary":"See where an invitation leads, before accepting it","tags":["Members"],"security":[{"session":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":10,"maxLength":200}},"required":["token"],"additionalProperties":false}}}},"responses":{"200":{"description":"The account and the role.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationPreview"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required, invitation_other_email.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: invitation_invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: invitation_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/locations":{"get":{"operationId":"listLocations","summary":"The account's locations","tags":["Places"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"Oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createLocation","summary":"Add a location: an office, a shop, a warehouse or a home","tags":["Places"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"kind":{"default":"place","type":"string","enum":["place","home"]},"home_of":{"description":"For a home: the member whose home it is.","type":"string","pattern":"^usr_[0-9a-z]{26}$"},"time_zone":{"description":"Only when it lies in another time zone than the account.","anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new location.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Location"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/locations/{id}":{"patch":{"operationId":"updateLocation","summary":"Rename a location, or set its own time zone","tags":["Places"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"time_zone":{"description":"null: the account's again.","anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The location, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Location"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/me":{"get":{"operationId":"getMe","summary":"The signed-in person, and the accounts they belong to","tags":["People"],"security":[{"session":[]}],"responses":{"200":{"description":"The person and their accounts, with their role in each.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateMe","summary":"Change the signed-in person's name or language","tags":["People"],"security":[{"session":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"locale":{"$ref":"#/components/schemas/Locale"}},"additionalProperties":false}}}},"responses":{"200":{"description":"The person, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/members":{"get":{"operationId":"listMembers","summary":"The members of the account, with their roles","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The Owner first, then Admins, then Operators.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/members/{person_id}":{"patch":{"operationId":"updateMember","summary":"Change a member's role","description":"Admin or Operator. The Owner's role changes only by transferring ownership.","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"person_id","in":"path","required":true,"schema":{"type":"string","pattern":"^usr_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin","operator"]}},"required":["role"],"additionalProperties":false}}}},"responses":{"200":{"description":"The member, with the new role.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Member"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal, owner_role_fixed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"removeMember","summary":"Remove a member from the account","description":"Their access to this account ends at once. The keys, apps and computers belong to the account and keep working. The Owner cannot be removed; make another member the Owner first.","tags":["Members"],"security":[{"session":[]}],"parameters":[{"name":"person_id","in":"path","required":true,"schema":{"type":"string","pattern":"^usr_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The person is no longer a member."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, account_personal, owner_cannot_leave.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/pairings/{id}/approve":{"post":{"operationId":"approvePairing","summary":"Connect the computer to the account","description":"The computer joins at once, at its suggested place: with a computer on the same network, or in the only location, or where most computers are; the first computer makes the first location and workstation. Its workstation is called «Νέα θέση» until a person names it (PUT /v1/computers/{id}/placement). With sign_out, this browser signs out afterwards, for an approval made on the same computer.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":8,"maxLength":24},"sign_out":{"default":false,"description":"Approved from the same computer: this browser signs out afterwards (PRODUCT §4.2).","type":"boolean"}},"required":["code"],"additionalProperties":false}}}},"responses":{"201":{"description":"The computer, where it went, and why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairingApproved"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found, pairing_code_invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, computer_key_in_use.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: pairing_code_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/pairings/{id}/deny":{"post":{"operationId":"denyPairing","summary":"Refuse the computer","description":"For «Όχι»: the computer does not join, and its program says so.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":8,"maxLength":24,"description":"As the person typed it: dashes, spaces and case do not matter."}},"required":["code"],"additionalProperties":false}}}},"responses":{"204":{"description":"Refused."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found, pairing_code_invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: pairing_code_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/pairings/lookup":{"post":{"operationId":"lookupPairing","summary":"Find the computer that shows this code","description":"Up to 10 tries in 10 minutes per person. The answer says which computer asks, to compare before saying yes.","tags":["Computers"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":8,"maxLength":24,"description":"As the person typed it: dashes, spaces and case do not matter."}},"required":["code"],"additionalProperties":false}}}},"responses":{"200":{"description":"The computer that asks to join.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairingRequest"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found, pairing_code_invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: pairing_code_expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/plan":{"get":{"operationId":"getPlan","summary":"The account's plan, and this month's jobs against it","description":"What the app's menu shows, and its notice to the Owner and the Admins at 80% and at 100% (PRODUCT §4.10). On free, the waiting jobs hold their place too: once the month is taken, new jobs on real printers answer 402 plan_limit_reached until resets_at. A paid plan never stops. With each day's printed jobs, last month's, the jobs the plan does not count, and the new jobs free's limit refused, for the page «Πλάνο και χρέωση».","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The plan, and this month in UTC.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPlan"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/plan/limit":{"get":{"operationId":"getPlanLimit","summary":"Whether the account's new jobs wait for next month, for every member","description":"What the Home of an Operator shows at free's limit: whether new jobs on real printers are refused, until when, and who changes the plan. Without the month's numbers, which only the Owner and the Admins see (GET /v1/plan).","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The limit, and whom to ask.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanLimit"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/plans":{"get":{"operationId":"listPlans","summary":"The plans an account may have","description":"Each plan's printed jobs a month, its price, and what the jobs above it cost, in cents without VAT (PRODUCT §4.10), so that the app writes no amount of its own. The same for every account.","tags":["Accounts"],"security":[{"session":[]}],"responses":{"200":{"description":"Free first, then by size.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanList"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-job-views":{"get":{"operationId":"listPrintJobViews","summary":"The views a person keeps of the jobs","description":"Only theirs, in this account, by name.","tags":["Print jobs"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The views.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobViewList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createPrintJobView","summary":"Keep a view of the jobs","description":"«Αποθήκευση προβολής»: the list's filters and order, by a name of the person's choosing.","tags":["Print jobs"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"filters":{"type":"object","properties":{"q":{"description":"Words in the title or the reference.","type":"string","minLength":1,"maxLength":100},"state":{"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","type":"string"},"shown_as":{"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","type":"string"},"needs_person":{"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","type":"string","const":"true"},"printer_id":{"description":"One printer's jobs, or several printers' separated by commas.","type":"string"},"workstation_id":{"description":"The jobs sent to this workstation.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"app_id":{"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","type":"string"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"created_after":{"description":"Made at or after this moment.","type":"string","format":"date-time"},"created_before":{"description":"Made before this moment.","type":"string","format":"date-time"},"reference":{"description":"Exactly this reference, e.g. an order number.","type":"string","minLength":1,"maxLength":200},"sort":{"description":"The order: -created_at, the newest first, by default.","$ref":"#/components/schemas/JobSort"}},"additionalProperties":false}},"required":["name","filters"],"additionalProperties":false}}}},"responses":{"201":{"description":"The view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobView"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken, too_many_views.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-job-views/{id}":{"patch":{"operationId":"updatePrintJobView","summary":"Rename a view, or keep other filters in it","tags":["Print jobs"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"filters":{"type":"object","properties":{"q":{"description":"Words in the title or the reference.","type":"string","minLength":1,"maxLength":100},"state":{"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","type":"string"},"shown_as":{"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","type":"string"},"needs_person":{"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","type":"string","const":"true"},"printer_id":{"description":"One printer's jobs, or several printers' separated by commas.","type":"string"},"workstation_id":{"description":"The jobs sent to this workstation.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"app_id":{"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","type":"string"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"created_after":{"description":"Made at or after this moment.","type":"string","format":"date-time"},"created_before":{"description":"Made before this moment.","type":"string","format":"date-time"},"reference":{"description":"Exactly this reference, e.g. an order number.","type":"string","minLength":1,"maxLength":200},"sort":{"description":"The order: -created_at, the newest first, by default.","$ref":"#/components/schemas/JobSort"}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"The view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobView"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deletePrintJobView","summary":"Delete a view","description":"Only the view: the jobs stay as they are.","tags":["Print jobs"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The view is gone."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs":{"post":{"operationId":"createPrintJob","summary":"Print a file, on a printer or at a workstation","description":"The file is checked against the printer before it is queued, and stored before the job shows. The Idempotency-Key is the id of this print in your own system: the same key never makes a second job (30 days). The same key with the same request answers 200 with the job it made; with another request, 409.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Your own id for this request: a new one for each thing you ask for, e.g. the id of the print in your system. The same request sent again with the same key makes nothing new: it answers with what the first one made.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printer_id":{"description":"The printer to print on. Send printer_id or workstation_id, one of them.","type":"string","pattern":"^prn_[0-9a-z]{26}$"},"workstation_id":{"description":"Instead of a printer: the workstation's printer that fits the size prints it, its own before its location's shared ones.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"content_type":{"$ref":"#/components/schemas/ContentType"},"source":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"description":"https, on a public address: Printaloo downloads it once, now."}},"required":["url"],"additionalProperties":false},{"type":"object","properties":{"base64":{"type":"string","minLength":1,"maxLength":28000000,"description":"The file itself, up to 20 MB."}},"required":["base64"],"additionalProperties":false}],"description":"The file: a url that Printaloo downloads once, now, or the file itself in base64."},"paper_size":{"description":"For pages, e.g. A4. Without a size, the printer's default.","$ref":"#/components/schemas/SizeName"},"label_size":{"description":"For labels, e.g. 100x150mm.","$ref":"#/components/schemas/SizeName"},"copies":{"default":1,"description":"How many, from 1 to 100.","type":"integer","minimum":1,"maximum":100},"orientation":{"default":"auto","$ref":"#/components/schemas/Orientation"},"options":{"default":{},"$ref":"#/components/schemas/JobOptions"},"ttl_seconds":{"default":900,"description":"How long it may take to reach the printer: 15 minutes by default, from 1 minute to 24 hours.","type":"integer","minimum":60,"maximum":86400},"title":{"description":"What people see the job as, e.g. Invoice 2024-1182. No customers' names: it is kept with the job.","type":"string","maxLength":200},"reference":{"description":"The app's own reference.","type":"string","maxLength":200}},"required":["content_type","source"],"additionalProperties":false}}}},"responses":{"200":{"description":"The job that this Idempotency-Key made before (Idempotent-Replayed: true).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"201":{"description":"The job, queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Problem: plan_limit_reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, idempotency_conflict, idempotency_key_used.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: file_invalid, file_too_large, file_unreachable, no_printer_fits, size_mismatch, size_unsupported, unsupported_option, zpl_dpi_mismatch, zpl_unsupported.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"operationId":"listPrintJobs","summary":"The account's print jobs","description":"An app with jobs:write sees the jobs it sent; jobs:read sees all of them. Nobody sees what prints at another person's home. Search finds words in the title and the reference. A page starts after a `cursor`, in order of created_at, or after an `offset`, in any order and with the `total`.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Words in the title or the reference.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"state","in":"query","required":false,"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","schema":{"type":"string"}},{"name":"shown_as","in":"query","required":false,"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","schema":{"type":"string"}},{"name":"needs_person","in":"query","required":false,"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","schema":{"type":"string","const":"true"}},{"name":"printer_id","in":"query","required":false,"description":"One printer's jobs, or several printers' separated by commas.","schema":{"type":"string"}},{"name":"workstation_id","in":"query","required":false,"description":"The jobs sent to this workstation.","schema":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"}},{"name":"app_id","in":"query","required":false,"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","schema":{"type":"string"}},{"name":"day","in":"query","required":false,"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","schema":{"anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]}},{"name":"created_after","in":"query","required":false,"description":"Made at or after this moment.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Made before this moment.","schema":{"type":"string","format":"date-time"}},{"name":"reference","in":"query","required":false,"description":"Exactly this reference, e.g. an order number.","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"sort","in":"query","required":false,"description":"The order: -created_at, the newest first, by default.","schema":{"$ref":"#/components/schemas/JobSort"}},{"name":"cursor","in":"query","required":false,"description":"The next_cursor of the previous page: in order of created_at, without offset.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,200}$"}},{"name":"offset","in":"query","required":false,"description":"Skip this many jobs; the page says the total.","schema":{"type":"integer","minimum":0,"maximum":1000000}},{"name":"limit","in":"query","required":false,"description":"Jobs a page: 50 by default, up to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"A page of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/{id}":{"get":{"operationId":"getPrintJob","summary":"One print job, with its timeline","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The job, and each of its states with when and who.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobDetail"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deletePrintJob","summary":"Delete a job, with its file","description":"For good: the job, its timeline, and its file when no other job uses it. A job that is done, or whose end nobody knows (unknown): its computer takes that one out of the queue of Windows, if it is there and the computer can. Cancel a job that waits or prints first. A person: the Owner and the Admins. An app: the jobs it sent.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The job is gone."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, job_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/{id}/cancel":{"post":{"operationId":"cancelPrintJob","summary":"Cancel a job before it prints","description":"A job that waits is cancelled at once. One its computer holds is asked of the computer, which takes it out of the printer's queue and reports: cancelled, or printed when it was too late.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The job: cancelled, or with cancel_requested_at.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, job_not_cancellable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/{id}/confirm":{"post":{"operationId":"confirmPrintJob","summary":"Say whether it came out right","description":"ok makes the job confirmed; not_ok makes it failed. Only a person knows whether it came out right: an app says it for the person who saw the paper. Once said, no later report of the computer changes it.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["ok","not_ok"],"description":"ok: it came out right. not_ok: it did not."}},"required":["outcome"],"additionalProperties":false}}}},"responses":{"200":{"description":"The job, confirmed or failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, job_decided, job_not_confirmable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/{id}/pages/{page}":{"get":{"operationId":"getPrintJobPage","summary":"A picture of one page of a job, as it prints","description":"A PNG of page `page` of the job's file, from 1 to file.pages, while file.preview is true. A PDF's page is drawn by the same PDFium as the program prints with: on paper in its own colours, at most 1600 pixels on its longer side; on a label printer as its dots, black or white at its dpi. A ZPL file's label `page` is drawn at its printer's dpi, on the job's label, black or white as it prints. A PNG is its own picture. The first request draws the page; later ones get the same picture, until the file is deleted, and the picture with it. Whoever sees the job sees its pages.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"page","in":"path","required":true,"description":"The page, from 1: a PDF's page, or a ZPL file's label.","schema":{"type":"integer","minimum":1,"maximum":1000000}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The page, as a PNG.","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"304":{"description":"The picture of the ETag in If-None-Match: it has not changed."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: file_gone.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: preview_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/{id}/reprint":{"post":{"operationId":"reprintPrintJob","summary":"Print a job again: the same file and settings, so the same paper","description":"A new job, tied to the first by reprint_of. On the same printer, or another that fits; whole, or from page N. It needs the file, while the account keeps it.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The job's id.","schema":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Your own id for this request: a new one for each thing you ask for, e.g. the id of the print in your system. The same request sent again with the same key makes nothing new: it answers with what the first one made.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printer_id":{"description":"Another printer that fits; the same printer when left out.","type":"string","pattern":"^prn_[0-9a-z]{26}$"},"from_page":{"description":"From this page of a PDF, or this label of a ZPL file.","type":"integer","minimum":1}},"additionalProperties":false}}}},"responses":{"200":{"description":"The job that this Idempotency-Key made before.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"201":{"description":"The new job, queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Problem: plan_limit_reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, idempotency_conflict, idempotency_key_used.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"Problem: file_gone.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: file_invalid, file_too_large, file_unreachable, no_printer_fits, page_out_of_range, size_mismatch, size_unsupported, unsupported_option, zpl_dpi_mismatch, zpl_unsupported.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/actions":{"post":{"operationId":"actOnPrintJobs","summary":"Do one thing for many jobs","description":"Confirm, reprint, move or cancel some jobs by id, or every job some filters find, 50 at a time. Each job as its own action would do it; one it does not apply to, or cannot take now, is in not_done with why, and the rest go on. The Idempotency-Key makes a request sent again print nothing twice. To delete, POST /v1/print-jobs/delete.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Your own id for this request: a new one for each thing you ask for, e.g. the id of the print in your system. The same request sent again with the same key makes nothing new: it answers with what the first one made.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"description":"What to do.","$ref":"#/components/schemas/JobAction"},"ids":{"description":"These jobs, by id. Send ids or filters, one of them.","minItems":1,"maxItems":50,"type":"array","items":{"type":"string","pattern":"^job_[0-9a-z]{26}$"}},"filters":{"description":"Every job these filters find, as GET /v1/print-jobs finds them, 50 at a time, the oldest first. Only those that were there when the first request came: not the jobs the action makes.","type":"object","properties":{"q":{"description":"Words in the title or the reference.","type":"string","minLength":1,"maxLength":100},"state":{"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","type":"string"},"shown_as":{"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","type":"string"},"needs_person":{"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","type":"string","const":"true"},"printer_id":{"description":"One printer's jobs, or several printers' separated by commas.","type":"string"},"workstation_id":{"description":"The jobs sent to this workstation.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"app_id":{"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","type":"string"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"created_after":{"description":"Made at or after this moment.","type":"string","format":"date-time"},"created_before":{"description":"Made before this moment.","type":"string","format":"date-time"},"reference":{"description":"Exactly this reference, e.g. an order number.","type":"string","minLength":1,"maxLength":200},"sort":{"description":"The order: -created_at, the newest first, by default.","$ref":"#/components/schemas/JobSort"}},"additionalProperties":false},"next":{"description":"With filters: the next of the previous answer.","type":"string","maxLength":400},"printer_id":{"description":"move: where to. reprint: another printer that fits; their own when left out.","type":"string","pattern":"^prn_[0-9a-z]{26}$"}},"required":["action"],"additionalProperties":false}}}},"responses":{"200":{"description":"What was done, what was not and why, and where to go on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobActionsResult"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/delete":{"post":{"operationId":"deletePrintJobs","summary":"Delete many jobs: by reference, made before a moment, by id, or all that some filters find","description":"For a customer who asks to be forgotten, by the reference your app gave their jobs (e.g. the order number); everything older than a date; some jobs by id; or every job some filters find. Jobs that wait or print stay, and are counted in active; those whose end nobody knows go, as DELETE /v1/print-jobs/{id} says. At most 1000 jobs a request: while more is true, send it again.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"reference":{"type":"string","minLength":1,"maxLength":200,"description":"Every job with this reference, e.g. when a customer asks to be forgotten."}},"required":["reference"],"additionalProperties":false},{"type":"object","properties":{"created_before":{"type":"string","format":"date-time","description":"Every job made before this moment."}},"required":["created_before"],"additionalProperties":false},{"type":"object","properties":{"ids":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"description":"These jobs, by id."}},"required":["ids"],"additionalProperties":false},{"type":"object","properties":{"filters":{"type":"object","properties":{"q":{"description":"Words in the title or the reference.","type":"string","minLength":1,"maxLength":100},"state":{"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","type":"string"},"shown_as":{"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","type":"string"},"needs_person":{"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","type":"string","const":"true"},"printer_id":{"description":"One printer's jobs, or several printers' separated by commas.","type":"string"},"workstation_id":{"description":"The jobs sent to this workstation.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"app_id":{"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","type":"string"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"created_after":{"description":"Made at or after this moment.","type":"string","format":"date-time"},"created_before":{"description":"Made before this moment.","type":"string","format":"date-time"},"reference":{"description":"Exactly this reference, e.g. an order number.","type":"string","minLength":1,"maxLength":200},"sort":{"description":"The order: -created_at, the newest first, by default.","$ref":"#/components/schemas/JobSort"}},"additionalProperties":false,"description":"Every job these filters find, as GET /v1/print-jobs finds them."}},"required":["filters"],"additionalProperties":false}],"description":"Which jobs: those with a reference, those made before a moment, some by id, or those some filters find."}}}},"responses":{"200":{"description":"How many were deleted, and how many still wait or print.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedJobs"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/print-jobs/today":{"get":{"operationId":"getPrintJobsToday","summary":"The day's numbers of the jobs","description":"What needs a person now, and the jobs of today, in the account's time zone: how many were sent, in each hour so far, how many printed, and how many a person said came out right. Of the jobs the caller sees, as the list; each number is one of its filters.","tags":["Print jobs"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The numbers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJobsToday"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printer-probes":{"post":{"operationId":"startPrinterProbe","summary":"Test an address before a printer goes in by hand","description":"One computer of the location asks the address whether it is a printer, without printing anything: with IPP, then at port 9100. Read the test every second until it is no longer testing; a found printer comes in with POST /v1/found-printers/{id}/add.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location_id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"},"address":{"type":"string","minLength":1,"maxLength":255,"description":"What a person typed: an IPv4 or IPv6 address, or a name."},"computer_id":{"description":"The computer that tests it: by default probe_computer, the one of the location that sees the most printers.","type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},"required":["location_id","address"],"additionalProperties":false}}}},"responses":{"201":{"description":"The test, started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterProbe"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, location_without_computer, no_computer_online.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printer-probes/{id}":{"get":{"operationId":"getPrinterProbe","summary":"A test of an address, as it goes","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prb_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterProbe"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printer-searches":{"post":{"operationId":"startPrinterSearch","summary":"Search the network of a location for printers","description":"The online computers of the location search their network for 10 seconds, and what they find comes in as it comes: read the search every second. A search that runs in the location already answers 200, so two people see the same one. Nothing found is added until a person adds it.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location_id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},"required":["location_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The search that runs in the location already.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterSearch"}}}},"201":{"description":"The search, started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterSearch"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, location_without_computer, no_computer_online.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printer-searches/{id}":{"get":{"operationId":"getPrinterSearch","summary":"A search, as it goes","description":"Its computers, what they found so far, and the computer that would test an address typed by hand.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^srh_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The search.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterSearch"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers":{"get":{"operationId":"listPrinters","summary":"The account's printers","description":"By place, the oldest first, and the virtual printer last. An API key with chosen printers sees only those. Windows' own software printers, and those a person hid, show only with include_hidden=true.","tags":["Printers"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"location_id","in":"query","required":false,"description":"Only the printers of this location.","schema":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},{"name":"workstation_id","in":"query","required":false,"description":"Only the printers of this workstation.","schema":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"}},{"name":"computer_id","in":"query","required":false,"description":"Only the printers of this computer.","schema":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"}},{"name":"include_hidden","in":"query","required":false,"description":"true: also Windows' software printers, and those a person hid.","schema":{"default":"false","type":"string","enum":["true","false"]}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The printers, with what each can do and how it is now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}":{"get":{"operationId":"getPrinter","summary":"One printer","description":"The id of a printer that a person later said is another one, e.g. after Windows renamed it, answers with that printer.","tags":["Printers"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The printer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updatePrinter","summary":"Name a printer, say what kind it is, hide it, or change Printaloo's defaults for it","description":"The printer's own settings (duplex, colour, tray, darkness, speed) change only on the printer. A new kind brings that kind's defaults, unless the request sets them too.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"null: back to the name Windows gives it.","anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"kind":{"$ref":"#/components/schemas/PrinterKind"},"zpl":{"description":"After a ZPL test label: whether it came out right. null: back to what the computer says.","type":["boolean","null"]},"hidden":{"type":"boolean"},"defaults":{"description":"Only Printaloo's own defaults: the printer's own settings change on the printer.","type":"object","properties":{"paper_size":{"$ref":"#/components/schemas/SizeName"},"label_size":{"$ref":"#/components/schemas/SizeName"},"scaling":{"$ref":"#/components/schemas/Scaling"}},"additionalProperties":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"The printer, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"removePrinter","summary":"Remove a printer that is not found","description":"For a printer that is gone for good. A printer that its computer finds stays: hide it instead. A removed printer's id never comes back; if the printer returns, it comes as a new one.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The printer is removed."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, printer_present.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}/pause":{"post":{"operationId":"pausePrinter","summary":"Pause a printer: its jobs wait","description":"«Παύση εκτυπωτή» (PRODUCT §4.3): its jobs wait until it goes on. The Operator can do it too.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The printer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}/placement":{"put":{"operationId":"placePrinter","summary":"Say where a printer is: at a workstation, shared by a location, or with its computer","description":"A printer starts at its computer's workstation, and goes wherever the computer goes until a person places it (PRODUCT §4.3). A shared printer, e.g. the copier of a floor, belongs to the whole location. A printer moves only within its computer's location: to take it to another location, move its computer.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"workstation_id":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"}},"required":["workstation_id"],"additionalProperties":false,"description":"At this workstation."},{"type":"object","properties":{"location_id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},"required":["location_id"],"additionalProperties":false,"description":"Shared by the whole location."},{"type":"object","properties":{"with_computer":{"type":"boolean","const":true}},"required":["with_computer"],"additionalProperties":false,"description":"Back with its computer, wherever it goes."}]}}}},"responses":{"200":{"description":"The printer, in its place.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}/relink":{"post":{"operationId":"relinkPrinter","summary":"Say which printer a lost one is now","description":"«Δεν βρέθηκε στα Windows: ποιος είναι τώρα;» (PRODUCT §4.3). When Windows makes a copy of a printer, or it gets a new name or address, its computer reports it as a new one. This printer, which is not found, takes the new one's place: it keeps its id, name, defaults and the keys that may use it, and the new one's id leads here from now on.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printer_id":{"type":"string","pattern":"^prn_[0-9a-z]{26}$","description":"The printer its computer finds now. This printer takes its place, and that id points here from now on."}},"required":["printer_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The printer, found again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, printer_missing, printer_present.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}/resume":{"post":{"operationId":"resumePrinter","summary":"Let a paused printer go on","description":"Its waiting jobs go on, in the order they were sent.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The printer's id.","schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The printer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/printers/{id}/test-page":{"post":{"operationId":"printTestPage","summary":"Print a test page","description":"«Δοκιμαστική σελίδα» (PRODUCT §4.3): a page on the printer's own size, with a frame a few millimetres from each edge. A job like any other, so its states show whether it printed; a person says whether it came out right.","tags":["Printers"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"description":"pdf when left out: a page on the printer's own size, a label's too. zpl: a ZPL label as it is, which tries the ZPL path of a label printer that takes ZPL.","type":"string","enum":["pdf","zpl"]}},"additionalProperties":false}}}},"responses":{"201":{"description":"The job of the test page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Problem: size_unsupported, zpl_unsupported.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions":{"delete":{"operationId":"signOutEverywhere","summary":"Sign out of every browser","description":"Every session of the signed-in person stops working at once, this one too. Meteorack Auth's sessions (FMB-5412) end with its library's sign-out everywhere, in the app's server.","tags":["Sessions"],"security":[{"session":[]}],"responses":{"204":{"description":"No session of this person works any more."},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current":{"delete":{"operationId":"signOut","summary":"Sign out of this browser","description":"In the program's window, of its device: the program's session and the app's it handed over end together (FMB-5241). A session of Meteorack Auth (FMB-5412) ends with Meteorack's library, in the app's server or the program; here it answers 204 and changes nothing.","tags":["Sessions"],"security":[{"session":[]}],"responses":{"204":{"description":"This session no longer works, nor any that shares its device."},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/usage":{"get":{"operationId":"getUsage","summary":"The account's usage, month by month","description":"Jobs as they are made, pages once they reach a printer, and the most computers at once. Months are in UTC.","tags":["Accounts"],"security":[{"session":[]}],"parameters":[{"name":"months","in":"query","required":false,"description":"How many months back, this one included.","schema":{"default":12,"type":"integer","minimum":1,"maximum":24}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"This month first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"The account's webhooks","description":"The oldest first.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The endpoints, without their secrets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createWebhook","summary":"Add a webhook","description":"An https endpoint on the public internet, and the events it hears. Each is signed as Standard Webhooks with the secret of this answer, which GET /v1/webhooks/{id}/secret shows again.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":9,"maxLength":2048,"description":"Where the messages go: https, on a public address."},"description":{"description":"What it is for, as people read it in the list.","type":"string","minLength":1,"maxLength":200},"events":{"minItems":1,"maxItems":3,"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"description":"What it hears: one event or more."}},"required":["url","events"],"additionalProperties":false}}}},"responses":{"201":{"description":"The endpoint, and its secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedWebhook"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required, webhook_events_not_allowed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, too_many_webhooks.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}":{"get":{"operationId":"getWebhook","summary":"One webhook","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateWebhook","summary":"Change a webhook's address or events, pause it, or turn it on again","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"description":"A new address: https, on a public address.","type":"string","minLength":9,"maxLength":2048},"description":{"description":"What it is for; null takes it away.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"events":{"description":"What it hears from now on: one event or more.","minItems":1,"maxItems":3,"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"status":{"description":"paused: nothing is sent, and what changes meanwhile is not told; what was waiting waits a day, then fails. active: on again, also after it was disabled.","type":"string","enum":["active","paused"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required, webhook_events_not_allowed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteWebhook","summary":"Delete a webhook","description":"With what it was sent: nothing more goes to it.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"204":{"description":"The endpoint is gone."},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/messages":{"get":{"operationId":"listWebhookMessages","summary":"What was sent to a webhook, newest first","description":"Its messages of the last 30 days, each with its last attempt.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"status","in":"query","required":false,"description":"Only the messages that wait, were delivered, or failed.","schema":{"$ref":"#/components/schemas/WebhookMessageStatus"}},{"name":"q","in":"query","required":false,"description":"Words in the title or the reference of the job a message tells of.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"cursor","in":"query","required":false,"description":"The next_cursor of the previous page.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,200}$"}},{"name":"limit","in":"query","required":false,"description":"Messages a page: 50 by default, up to 100.","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"A page of the history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMessageList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/messages/{message_id}":{"get":{"operationId":"getWebhookMessage","summary":"One message to a webhook, with every attempt","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"message_id","in":"path","required":true,"description":"The message's id.","schema":{"type":"string","pattern":"^msg_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The message, what it sent, and the endpoint's answers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMessageDetail"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/messages/{message_id}/resend":{"post":{"operationId":"resendWebhookMessage","summary":"Send a message again","description":"It goes at once, with the same webhook-id and body. One that waits keeps its schedule after this attempt; one that was delivered or failed is tried once. One that was delivered stays delivered.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"message_id","in":"path","required":true,"description":"The message's id.","schema":{"type":"string","pattern":"^msg_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"202":{"description":"It goes right after this answer: the message shows how it went.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMessage"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, webhook_not_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/messages/resend":{"post":{"operationId":"resendWebhookMessages","summary":"Send several messages again","description":"Sends up to 100 messages again, each as one. Each counts as a send, of 100 a minute per account. The ids of other webhooks' messages are not resent.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"message_ids":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","pattern":"^msg_[0-9a-z]{26}$"},"description":"The messages to send again, by id."}},"required":["message_ids"],"additionalProperties":false}}}},"responses":{"202":{"description":"They go right after this answer: each message shows how it went.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResentWebhookMessages"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, webhook_not_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","summary":"Give a webhook a new secret","description":"The new secret signs from now on. The old one signs too for the grace asked for, an hour by default, so that the app changes over without missing a webhook: meanwhile each carries both signatures. Grace none stops it at once.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"grace":{"default":"1h","description":"How long the old secret signs too, so that the app can change over: an hour by default, as for API keys.","type":"string","enum":["none","1h","24h","7d"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The new secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/secret":{"get":{"operationId":"getWebhookSecret","summary":"Show a webhook's secret","description":"For the app that checks the signatures. Each time it is shown, the audit log says who saw it.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"The secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}/test":{"post":{"operationId":"sendTestWebhook","summary":"Send a test message","description":"A webhook.test message, with the webhook as data, signed like every other. It goes once and at once, whatever events the webhook hears.","tags":["Webhooks"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook's id.","schema":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"202":{"description":"It goes right after this answer: the message shows how it went.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMessage"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, webhook_not_active.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/workstations":{"get":{"operationId":"listWorkstations","summary":"The account's workstations, or those of one location","tags":["Places"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[{"name":"location_id","in":"query","required":false,"description":"Only the workstations of this location.","schema":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"responses":{"200":{"description":"By location, oldest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkstationList"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createWorkstation","summary":"Add a workstation to a location","tags":["Places"],"security":[{"session":[]}],"parameters":[{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"location_id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"},"name":{"type":"string","minLength":1,"maxLength":120}},"required":["location_id","name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new workstation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workstation"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/workstations/{id}":{"patch":{"operationId":"updateWorkstation","summary":"Rename a workstation, or move it to another location","tags":["Places"],"security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"}},{"name":"Printaloo-Account","in":"header","required":false,"description":"For a person's session: the account to act in (`acc_…`). An API key or a computer always acts in its own account.","schema":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"location_id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"}},"additionalProperties":false}}}},"responses":{"200":{"description":"The workstation, changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workstation"}}}},"400":{"description":"Problem: invalid_request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Problem: unauthorized.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Problem: forbidden, https_required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Problem: not_found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Problem: account_deleting, name_taken.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Problem: payload_too_large.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Problem: unsupported_media_type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Problem: rate_limited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Problem: internal_error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Problem: service_unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{"job.state_changed":{"post":{"summary":"A job's state changed","description":"At every change of state, with the job and its sequence. Two may arrive in the other order: keep the job with the highest sequence. A job printed at a person's home goes only to the webhooks that person made.","tags":["Webhooks"],"parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The message's id (msg_…): the same on every attempt of it, so keep each one once.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"When this attempt was signed, in seconds since 1970 (UTC). Refuse one more than 5 minutes away.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"v1, a comma and the base64 HMAC-SHA256 of `webhook-id.webhook-timestamp.body`, with the secret after whsec_ decoded from base64. After a rotation there are two, with a space between: one that matches is enough.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStateChangedWebhook"}}}},"responses":{"2XX":{"description":"It arrived. Any other answer, or none in 15 seconds, and it goes again after 5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h; an endpoint that fails for 3 days stops."}}}},"printer.updated":{"post":{"summary":"A printer changed","description":"A printer was added, its status, capabilities, settings or place changed, it was paused, or it was removed.","tags":["Webhooks"],"parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The message's id (msg_…): the same on every attempt of it, so keep each one once.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"When this attempt was signed, in seconds since 1970 (UTC). Refuse one more than 5 minutes away.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"v1, a comma and the base64 HMAC-SHA256 of `webhook-id.webhook-timestamp.body`, with the secret after whsec_ decoded from base64. After a rotation there are two, with a space between: one that matches is enough.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrinterUpdatedWebhook"}}}},"responses":{"2XX":{"description":"It arrived. Any other answer, or none in 15 seconds, and it goes again after 5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h; an endpoint that fails for 3 days stops."}}}},"computer.updated":{"post":{"summary":"A computer changed","description":"A computer came online or went offline, moved, or was removed.","tags":["Webhooks"],"parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The message's id (msg_…): the same on every attempt of it, so keep each one once.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"When this attempt was signed, in seconds since 1970 (UTC). Refuse one more than 5 minutes away.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"v1, a comma and the base64 HMAC-SHA256 of `webhook-id.webhook-timestamp.body`, with the secret after whsec_ decoded from base64. After a rotation there are two, with a space between: one that matches is enough.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerUpdatedWebhook"}}}},"responses":{"2XX":{"description":"It arrived. Any other answer, or none in 15 seconds, and it goes again after 5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h; an endpoint that fails for 3 days stops."}}}},"webhook.test":{"post":{"summary":"A test","description":"What POST /v1/webhooks/{id}/test sends, once and with the webhook as data, so that the app can check that its endpoint answers and that it checks the signature. Every webhook gets it, whatever events it hears.","tags":["Webhooks"],"parameters":[{"name":"webhook-id","in":"header","required":true,"description":"The message's id (msg_…): the same on every attempt of it, so keep each one once.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"When this attempt was signed, in seconds since 1970 (UTC). Refuse one more than 5 minutes away.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"v1, a comma and the base64 HMAC-SHA256 of `webhook-id.webhook-timestamp.body`, with the secret after whsec_ decoded from base64. After a rotation there are two, with a space between: one that matches is enough.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestWebhook"}}}},"responses":{"2XX":{"description":"It arrived. Any other answer, or none in 15 seconds, and it goes again after 5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h; an endpoint that fails for 3 days stops."}}}}},"components":{"schemas":{"Account":{"type":"object","properties":{"id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"name":{"type":"string"},"kind":{"$ref":"#/components/schemas/AccountKind"},"locale":{"$ref":"#/components/schemas/Locale"},"file_retention":{"$ref":"#/components/schemas/FileRetention"},"time_zone":{"type":"string","description":"IANA, e.g. Europe/Athens: where the account's day starts, and the times on its test pages."},"deletion":{"$ref":"#/components/schemas/AccountDeletion"},"created_at":{"type":"string","format":"date-time"}},"required":["id","name","kind","locale","file_retention","time_zone","deletion","created_at"],"additionalProperties":false,"description":"A company's, or one person's: it has places, devices and jobs, and a company's has members too."},"AccountDeletion":{"anyOf":[{"type":"object","properties":{"requested_at":{"type":"string","format":"date-time"},"purge_at":{"type":"string","format":"date-time","description":"When everything in it is deleted for good. Until then the Owner can restore it."}},"required":["requested_at","purge_at"],"additionalProperties":false},{"type":"null"}],"description":"Set while the account is being deleted: its Owner may still restore it."},"AccountKind":{"type":"string","enum":["company","personal"],"description":"company: a company's, with members, their roles and invitations. personal: one person's alone, without members; otherwise the same. A personal account becomes a company's, never back."},"AccountMembership":{"type":"object","properties":{"id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"name":{"type":"string"},"kind":{"$ref":"#/components/schemas/AccountKind"},"role":{"$ref":"#/components/schemas/Role"},"deletion":{"$ref":"#/components/schemas/AccountDeletion"}},"required":["id","name","kind","role","deletion"],"additionalProperties":false,"description":"An account the person belongs to, with their role there. One being deleted shows only to its Owner."},"AccountPlan":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/Plan"},"pilot":{"type":"boolean","description":"An account of the pilot: its plan, and the jobs it prints above it, cost nothing while the pilot lasts."},"jobs":{"type":"integer","description":"The plan's printed jobs in a month."},"month":{"type":"string","description":"This month, in UTC, e.g. 2026-10."},"printed":{"type":"integer","description":"Jobs printed this month: the number of the app's menu, as printed_jobs of the usage."},"waiting":{"type":"integer","description":"Jobs on real printers that may still print, test pages apart. On free, they hold their place in the month."},"extra":{"type":"integer","description":"Jobs printed this month above the plan's: a paid plan pays them with the next month, the pilot never."},"state":{"$ref":"#/components/schemas/PlanState"},"stopped":{"type":"boolean","description":"Free, with the month's jobs used: new jobs on real printers are refused (plan_limit_reached) until resets_at."},"resets_at":{"type":"string","format":"date-time","description":"When the month's count starts again: the 1st of next month, 00:00 UTC."},"days":{"type":"array","items":{"$ref":"#/components/schemas/PlanDay"},"description":"Each day of this month, from the 1st to today in UTC, with its printed jobs: the month's bars."},"printed_last_month":{"type":"integer","description":"The jobs printed last month: in the month's first days, its pace alone says too little of it."},"not_counted":{"$ref":"#/components/schemas/NotCounted"},"refused":{"type":"integer","description":"New jobs that free's limit refused this month (plan_limit_reached): they print only if they are sent again."},"refused_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the first of them was refused; null when none was."}},"required":["plan","pilot","jobs","month","printed","waiting","extra","state","stopped","resets_at","days","printed_last_month","not_counted","refused","refused_since"],"additionalProperties":false,"description":"The account's plan, and this month's jobs against it. A plan counts the jobs printed on real printers, once each, without the virtual printer and test pages. Computers, printers, members, apps, keys and webhooks have no limit."},"ActorRef":{"type":"object","properties":{"type":{"type":"string","enum":["person","key","computer","app","system"]},"id":{"type":["string","null"]},"name":{"description":"A person's name, or a key's, or a computer's.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false,"description":"Who did something: a person, an app by its API key, a computer's program, or Printaloo."},"AgentJobReason":{"type":"string","enum":["printer_refused","file_unreadable","option_unsupported","printer_gone","computer_error","not_in_time","cancelled","outcome_unknown"],"description":"Why a job failed, expired or was cancelled on the computer. outcome_unknown goes with spooled: the computer started again while it was sending the job, and cannot know whether it came out; a person says."},"AgentPrinter":{"type":"object","properties":{"id":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"},"ref":{"description":"The handle the program reported it with.","type":["string","null"]},"name":{"type":"string"},"kind":{"$ref":"#/components/schemas/PrinterKind"},"paused":{"type":"boolean"},"hidden":{"type":"boolean"},"missing_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Since when the program does not report it: its window asks which printer it is now."}},"required":["id","ref","name","kind","paused","hidden","missing_since"],"additionalProperties":false,"description":"A printer of this computer, as its program keeps it: by the id the server gave it."},"AgentPrinterList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AgentPrinter"}}},"required":["data"],"additionalProperties":false},"AgentRelease":{"type":"object","properties":{"version":{"type":"string","pattern":"^(0|[1-9][0-9]{0,3})\\.(0|[1-9][0-9]{0,3})\\.(0|[1-9][0-9]{0,3})$"},"download_path":{"type":"string","description":"Where its installer downloads, on this API. The program downloads only from the API it is connected to."},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"The SHA-256 of the installer, in hex."},"size":{"type":"integer","description":"The installer's size, in bytes."},"signature":{"type":"string","pattern":"^[A-Za-z0-9_-]{86}$","description":"Printaloo's Ed25519 signature over the version, the SHA-256 and the size (docs/api/AGENT.md §7), in base64url. The program checks it with the key it carries before it runs the installer."},"published_at":{"type":"string","format":"date-time"}},"required":["version","download_path","sha256","size","signature","published_at"],"additionalProperties":false,"description":"A release of the Printaloo program for Windows: its installer, and the signature that vouches for it."},"ApiKey":{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[0-9a-z]{26}$"},"app_id":{"type":"string","pattern":"^key_[0-9a-z]{26}$","description":"Its app, the same after a new secret: the id of the app's first key, as GET /v1/apps, a job's app.id and the list's app_id say."},"name":{"type":"string"},"prefix":{"type":"string","description":"The start of the key, to recognise it: `pl_` and 8 characters."},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"printer_access":{"type":"string","enum":["all","selected"]},"printer_ids":{"type":"array","items":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"},"description":"The printers of a key with printer_access `selected`; empty for `all`."},"status":{"$ref":"#/components/schemas/ApiKeyStatus"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}]},"app_created_at":{"type":"string","format":"date-time","description":"When its app was made: its first key's created_at, the same after a new secret."},"app_created_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}],"description":"Who made its app: its first key's created_by, the same after a new secret."},"stopped_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"stopped_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}],"description":"Who stopped it, while it is stopped; null when an API key did."},"restorable_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"A stopped key can be resumed until then; after it, it never works again."},"grace_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"A replaced key works until then."},"previous":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[0-9a-z]{26}$"},"prefix":{"type":"string"},"works_until":{"type":"string","format":"date-time","description":"The old key works until then."},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the app last used the old key: if after this key was made, it has not changed over yet."}},"required":["id","prefix","works_until","last_used_at"],"additionalProperties":false},{"type":"null"}],"description":"The key this one replaced, while it still works: the list shows it here, not as a row of its own. «Σταμάτα το παλιό τώρα» is POST /v1/api-keys/{id}/revoke on it."}},"required":["id","app_id","name","prefix","scopes","printer_access","printer_ids","status","expires_at","last_used_at","created_at","created_by","app_created_at","app_created_by","stopped_at","stopped_by","restorable_until","grace_until","previous"],"additionalProperties":false,"description":"Access for the account's own apps and scripts. Its secret is shown only when it is made."},"ApiKeyList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["data"],"additionalProperties":false},"ApiKeyScope":{"type":"string","enum":["printers:read","jobs:read","jobs:write","webhooks:manage"],"description":"printers:read: see places, computers and printers. jobs:read: see every job. jobs:write: print, and see, cancel, confirm, reprint and delete the jobs this key sent. webhooks:manage: manage the account's webhooks."},"ApiKeyStatus":{"type":"string","enum":["active","stopped","rotating","expired"],"description":"active: works. stopped: does not work, and can be resumed until restorable_until. rotating: replaced, and works until grace_until. expired: its date passed."},"App":{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[0-9a-z]{26}$","description":"The id of its first API key: what a job's app.id and the list's app_id say."},"name":{"type":"string","description":"The name of its newest key."}},"required":["id","name"],"additionalProperties":false,"description":"An app that prints for the account: an API key, and the keys that replaced it."},"AppList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/App"}}},"required":["data"],"additionalProperties":false},"AttentionCode":{"type":"string","enum":["computer_offline","computer_removed","not_found","paused","printer_offline","paper_out","paper_jam","door_open","supply_out","paused_in_windows","other","unknown","failed","expired"],"description":"What a person must do for a job now. unknown: nobody knows whether it printed; say whether it came out (confirm). A printer's reason (paper_out, computer_offline…): fix what holds it, or send it elsewhere. failed, expired: it did not print in the last 24 hours, and nobody printed it again."},"AuditEvent":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"action":{"type":"string","description":"What happened, as subject.verb: account.created, account.updated, account.deleted, account.restored, owner.transferred, member.invited, member.joined, member.role_changed, member.removed, member.left, invitation.revoked, key.created, key.updated, key.stopped, key.resumed, key.rotated, key.revoked, computer.paired, pairing.denied, computer.moved, computer.replaced, computer.removed, workstation.moved, printer.added, printer.relinked, printer.removed, job.deleted, jobs.deleted, webhook.created, webhook.updated, webhook.deleted, webhook.secret_viewed, webhook.secret_rotated, webhook.disabled. jobs.deleted keeps only how many, and by what (reference, date, ids or filters): never the reference or the search itself."},"actor":{"$ref":"#/components/schemas/ActorRef"},"target":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","description":"account, person, invitation, key, computer, pairing, workstation, printer, job or webhook."},"id":{"type":"string"},"name":{"description":"Its name now, or when it happened if it is gone.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false},{"type":"null"}]},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"What else matters for this action, e.g. the role before and after."}},"required":["id","at","action","actor","target","details"],"additionalProperties":false,"description":"One change of access: who did what, to what, and when."},"AuditEventList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"next_cursor":{"description":"For the next page, as `cursor`; null on the last page, and with offset.","type":["string","null"]},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many lines match, for a page asked with offset; null with a cursor."}},"required":["data","next_cursor","total"],"additionalProperties":false},"AuditEventView":{"type":"object","properties":{"id":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"},"name":{"type":"string"},"filters":{"type":"object","properties":{"q":{"description":"Words in the name of what changed, or of who changed it. Not in the details of a line.","type":"string","minLength":1,"maxLength":100},"actor_id":{"description":"Only what these did: people, keys or computers, separated by commas.","type":"string"},"subject":{"description":"Only these kinds of lines, separated by commas.","type":"string"},"target_id":{"description":"Only the lines about this key, computer, person or printer.","type":"string","pattern":"^[a-z]{3}_[0-9a-z]{26}$"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"from":{"description":"From this moment on.","type":"string","format":"date-time"},"to":{"description":"Before this moment.","type":"string","format":"date-time"},"sort":{"$ref":"#/components/schemas/AuditSort"}},"additionalProperties":false,"description":"GET /v1/audit-events with these shows the view."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","filters","created_at","updated_at"],"additionalProperties":false,"description":"«Αποθήκευση προβολής»: a list of the log a person keeps by name. Only they see it."},"AuditEventViewList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEventView"}}},"required":["data"],"additionalProperties":false},"AuditSort":{"type":"string","enum":["-at","at","action","-action","actor","-actor"],"description":"A column, with a minus for the other way. -at, the newest first, by default. action groups what happened by its subject; actor goes by who did it, as people read names, and Printaloo itself last."},"AuditSubject":{"type":"string","enum":["account","member","invitation","key","computer","location","printer","job","webhook"],"description":"What a line is about, by the first word of its action: account (account.*, owner.*), member, invitation, key, computer (computer.*, pairing.*), location (location.*, workstation.*), printer, job (job.*, jobs.*) and webhook."},"ClaimedJob":{"type":"object","properties":{"id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"claim_id":{"type":"string","pattern":"^clm_[0-9a-z]{26}$","description":"Say it with every report about this job: a report for an older claim is refused."},"printer_id":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"},"printer_ref":{"description":"The handle the program reported the printer with.","type":["string","null"]},"content_type":{"$ref":"#/components/schemas/ContentType"},"file":{"type":"object","properties":{"url":{"type":"string","description":"GET it, signed as the computer. Check its SHA-256 before printing."},"size_bytes":{"type":"integer"},"sha256":{"type":"string"}},"required":["url","size_bytes","sha256"],"additionalProperties":false},"paper_size":{"type":["string","null"]},"label_size":{"type":["string","null"]},"paper":{"anyOf":[{"type":"object","properties":{"width_mm":{"type":"number"},"height_mm":{"type":"number"}},"required":["width_mm","height_mm"],"additionalProperties":false},{"type":"null"}],"description":"The size it prints on. A label's page up to 10% larger is made smaller to fit."},"scaling":{"$ref":"#/components/schemas/Scaling"},"orientation":{"$ref":"#/components/schemas/Orientation"},"copies":{"type":"integer"},"options":{"description":"Only what the job asked; the printer's own settings for the rest, and back to them after.","$ref":"#/components/schemas/JobOptions"},"from_page":{"anyOf":[{"type":"integer"},{"type":"null"}]},"title":{"type":["string","null"]},"expires_at":{"type":"string","format":"date-time","description":"After it, the job must not print: take it out of the printer's queue, and report expired."}},"required":["id","claim_id","printer_id","printer_ref","content_type","file","paper_size","label_size","paper","scaling","orientation","copies","options","from_page","title","expires_at"],"additionalProperties":false,"description":"A job this computer took: write it in the journal, then send it to the printer."},"ClaimedJobList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ClaimedJob"}},"server_time":{"type":"string","format":"date-time"}},"required":["data","server_time"],"additionalProperties":false,"description":"At most one job per printer: the first of its queue."},"ColorMode":{"type":"string","enum":["color","monochrome"],"description":"In colour, or in black and white."},"Computer":{"type":"object","properties":{"id":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"},"name":{"type":"string","description":"What Windows calls it. People know a computer by its workstation."},"os":{"type":["string","null"]},"agent_version":{"type":["string","null"]},"status":{"type":"string","enum":["online","offline"]},"last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"offline_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Since when it has not answered; null while it is online."},"location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"workstation":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"paired_at":{"type":"string","format":"date-time"},"paired_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}]},"printers":{"type":"integer","description":"How many printers it brings."}},"required":["id","name","os","agent_version","status","last_seen_at","offline_since","location","workstation","paired_at","paired_by","printers"],"additionalProperties":false,"description":"A computer with the Printaloo program: it brings its printers and those of its network."},"ComputerList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Computer"}}},"required":["data"],"additionalProperties":false},"ComputerUpdatedWebhook":{"type":"object","properties":{"type":{"type":"string","const":"computer.updated"},"timestamp":{"type":"string","format":"date-time","description":"When it changed."},"account_id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"changes":{"type":"array","items":{"type":"string"},"description":"What changed: status (online or offline), placement, removed."},"data":{"anyOf":[{"$ref":"#/components/schemas/Computer"},{"$ref":"#/components/schemas/GoneSubject"}],"description":"The subject as it was: a job at the change the message tells of, a printer or a computer when the message first left. The same on every attempt."}},"required":["type","timestamp","account_id","changes","data"],"additionalProperties":false},"ContentType":{"type":"string","enum":["pdf","zpl","png"],"description":"pdf: a document or a label. zpl: raw ZPL, for a label printer that takes it. png: one picture, one page."},"CreatedApiKey":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","description":"The key itself, `pl_…`, shown only now. Keep it like a password."}},"required":["key","secret"],"additionalProperties":false},"CreatedInvitation":{"type":"object","properties":{"invitation":{"$ref":"#/components/schemas/Invitation"},"token":{"type":"string","description":"Shown only now. The app puts it in the link it gives to copy."}},"required":["invitation","token"],"additionalProperties":false},"CreatedSession":{"type":"object","properties":{"token":{"type":"string","description":"Shown only now: the bearer token of this session."},"session":{"$ref":"#/components/schemas/Session"},"person":{"$ref":"#/components/schemas/Person"}},"required":["token","session","person"],"additionalProperties":false},"CreatedWebhook":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"secret":{"type":"string"}},"required":["webhook","secret"],"additionalProperties":false},"DataExport":{"type":"object","properties":{"id":{"anyOf":[{"type":"string","pattern":"^exp_[0-9a-z]{26}$"},{"type":"null"}],"description":"Null when there is none."},"status":{"$ref":"#/components/schemas/DataExportStatus"},"progress":{"type":"integer","minimum":0,"maximum":100,"description":"How far it got, in percent: 100 once ready."},"file_name":{"description":"The ZIP's name: the account's name and the day it was asked for.","type":["string","null"]},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The ZIP's size, once ready."},"contents":{"anyOf":[{"$ref":"#/components/schemas/DataExportContents"},{"type":"null"}],"description":"What it holds, counted when it was asked for."},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"ready_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"failed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it is deleted: 7 days after it was ready."},"seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the person who asked saw that it is ready, or that it failed. Until then the app tells them, in the bell and once on any page."}},"required":["id","status","progress","file_name","size_bytes","contents","created_at","ready_at","failed_at","expires_at","seen_at"],"additionalProperties":false,"description":"The ZIP of the account's data that the caller asked for. Each Owner and Admin has their own, with what they see: the jobs and the files of a person's home are only in that person's."},"DataExportContents":{"type":"object","properties":{"jobs":{"type":"integer","description":"The jobs, in print-jobs.csv: those the person who asks sees, never those of another person's home."},"audit_events":{"type":"integer","description":"The lines of the audit log, in audit-events.csv."},"files":{"type":"integer","description":"The files we keep of those jobs, in the folder files."},"file_bytes":{"type":"integer","description":"Their size, in bytes."}},"required":["jobs","audit_events","files","file_bytes"],"additionalProperties":false,"description":"What a ZIP of the account's data holds (S05): the jobs and the audit log in CSV, and the files we keep."},"DataExportLink":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Download the ZIP from here, without a header: it works for an hour, and resumes with Range."},"expires_at":{"type":"string","format":"date-time"}},"required":["url","expires_at"],"additionalProperties":false,"description":"A link a browser downloads the ZIP from."},"DataExportStatus":{"type":"string","enum":["none","preparing","ready","failed"],"description":"none: nobody asked, or it expired. preparing: the ZIP is being made, a little every minute. ready: it can be downloaded until expires_at. failed: it could not be made; ask again."},"DeletedJobs":{"type":"object","properties":{"deleted":{"type":"integer","description":"Jobs deleted now, with their files when no other job used them."},"active":{"type":"integer","description":"Jobs that match but wait or print: cancel them first."},"more":{"type":"boolean","description":"More jobs match than one request deletes (1000): send it again."}},"required":["deleted","active","more"],"additionalProperties":false},"Duplex":{"type":"string","enum":["one_sided","long_edge","short_edge"],"description":"one_sided; or on both sides, turned on the long edge (like a book) or on the short edge (like a notepad)."},"EmailCodeSent":{"type":"object","properties":{"flow":{"type":"string","description":"This code's sign-in, for its check. Each code has its own: keep only the newest."},"code_expires_in":{"type":"integer","description":"Seconds the code works: 600."},"resend_after":{"type":"integer","description":"Seconds the page waits before it offers another code: 60."},"attempts":{"type":"integer","description":"Wrong tries the code takes: 5."}},"required":["flow","code_expires_in","resend_after","attempts"],"additionalProperties":false,"description":"A 6-digit code went to the email. The answer is the same whether the address has an account or not."},"FieldError":{"type":"object","properties":{"path":{"type":"string","description":"Where in the request, e.g. `body.copies`."},"code":{"type":"string","description":"A stable code for this field error."},"message":{"type":"string","description":"What is wrong, in the language of the request."}},"required":["path","code","message"],"additionalProperties":false},"FileRetention":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"keep"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"after_print"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"days"},"days":{"type":"integer","minimum":1,"maximum":3650}},"required":["mode","days"],"additionalProperties":false}],"description":"When the files of jobs are deleted by themselves. keep: never, until the account deletes them (the default). after_print: once printed. days: that many days after they came, from 1 to 3650."},"FileRetentionPreview":{"type":"object","properties":{"files":{"type":"integer","description":"The files it deletes, all at once, within minutes of «Αποθήκευση»."},"jobs":{"type":"integer","description":"The jobs whose file that is: they stay in the list, without their preview and «Τύπωσε ξανά» (S03b)."}},"required":["files","jobs"],"additionalProperties":false,"description":"What a choice of file retention would delete now, if saved. Never a file that a job still waits for."},"FoundPrinter":{"type":"object","properties":{"id":{"type":"string","pattern":"^fnd_[0-9a-z]{26}$"},"name":{"type":"string","description":"What the printer calls itself on the network."},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"kind":{"anyOf":[{"$ref":"#/components/schemas/PrinterKind"},{"type":"null"}],"description":"null: its computer could not tell."},"color":{"description":"Whether it prints in color; null when it does not say.","type":["boolean","null"]},"paper":{"description":"The size it is set to, e.g. A4 or 100x150mm, when it says.","type":["string","null"]},"location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"address":{"description":"Its address on the network, as the computer that saw it last reached it.","type":["string","null"]},"protocol":{"type":"string","enum":["ipp","ipps","socket"],"description":"ipp or ipps, for pages; socket: port 9100, for labels."},"seen_by":{"type":"array","items":{"type":"object","properties":{"computer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"at":{"type":"string","format":"date-time"}},"required":["computer","at"],"additionalProperties":false},"description":"The computers that see it, the latest first."},"last_seen_at":{"type":"string","format":"date-time"},"printer_id":{"anyOf":[{"type":"string","pattern":"^prn_[0-9a-z]{26}$"},{"type":"null"}],"description":"When it is already a printer of the account: one a person added, or the same printer in a computer's Windows."}},"required":["id","name","make","model","kind","color","paper","location","address","protocol","seen_by","last_seen_at","printer_id"],"additionalProperties":false,"description":"A printer that a computer sees on the network, and reaches without a driver."},"FoundPrinterList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FoundPrinter"}}},"required":["data"],"additionalProperties":false},"GoneSubject":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"],"additionalProperties":false,"description":"Only the id: the subject is gone, or the person who made the webhook cannot see it."},"Health":{"type":"object","properties":{"status":{"type":"string","const":"ok"},"database":{"type":"string","const":"ok"},"time":{"type":"string","format":"date-time","description":"The server's time, from the database's clock."}},"required":["status","database","time"],"additionalProperties":false,"description":"The API answers and reaches its database."},"Invitation":{"type":"object","properties":{"id":{"type":"string","pattern":"^inv_[0-9a-z]{26}$"},"role":{"type":"string","enum":["admin","operator"]},"email":{"type":["string","null"]},"name":{"description":"Whom it is meant for, by name, as the person who invited wrote it.","type":["string","null"]},"status":{"type":"string","enum":["pending","expired"],"description":"pending: the link works. expired: it no longer does; the list keeps it 30 days, unless deleted."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}]}},"required":["id","role","email","name","status","created_at","expires_at","created_by"],"additionalProperties":false,"description":"A link that lets one person join the account, until it is used, revoked or expires."},"InvitationList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}},"required":["data"],"additionalProperties":false},"InvitationPreview":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"role":{"type":"string","enum":["admin","operator"]},"expires_at":{"type":"string","format":"date-time"},"invited_by":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}],"description":"«Σε κάλεσε»: who made it, by name only, since whoever has the link reads it. null without a name."}},"required":["account","role","expires_at","invited_by"],"additionalProperties":false,"description":"What an invitation leads to, before the person accepts it."},"JobAction":{"type":"string","enum":["confirm","reprint","move","cancel"],"description":"confirm: a person says they came out right. reprint: prints again those that are done and those whose end nobody knows, on their printer or printer_id. move: sends those that wait to printer_id: each is cancelled and printed there, at once, so it never prints twice. cancel: cancels those that wait or print."},"JobActionsResult":{"type":"object","properties":{"done":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"made":{"anyOf":[{"type":"string","pattern":"^job_[0-9a-z]{26}$"},{"type":"null"}],"description":"reprint, move: the new job."}},"required":["id","made"],"additionalProperties":false},"description":"The jobs it did it to."},"not_done":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"code":{"type":"string","description":"A problem's code, e.g. job_not_cancellable, job_at_computer, file_gone."},"message":{"type":"string","description":"Why, and what to do, in the language of the request."}},"required":["id","code","message"],"additionalProperties":false},"description":"Ticked jobs it does not apply to, and jobs it could not do now."},"next":{"description":"With filters: more jobs match than one request does (50). Send it again with this as next.","type":["string","null"]}},"required":["done","not_done","next"],"additionalProperties":false},"JobFile":{"type":"object","properties":{"size_bytes":{"type":"integer"},"pages":{"type":"integer","description":"A PDF's pages, a ZPL file's labels; 1 for a PNG."},"sha256":{"type":"string"},"kept":{"type":"boolean","description":"Whether the file is still kept: a reprint needs it."},"preview":{"type":"boolean","description":"Whether its pages have pictures, at GET /v1/print-jobs/{id}/pages/{n}: while the file is kept, and as long as Printaloo can draw it."}},"required":["size_bytes","pages","sha256","kept","preview"],"additionalProperties":false},"JobOptions":{"type":"object","properties":{"duplex":{"$ref":"#/components/schemas/Duplex"},"color":{"$ref":"#/components/schemas/ColorMode"},"tray":{"description":"An id of the printer's capabilities.trays; only with printer_id.","type":"string","minLength":1,"maxLength":64},"darkness":{"description":"On a ZPL printer: one of its capabilities.darkness.","type":"number","minimum":-100,"maximum":100},"speed_ips":{"description":"On a ZPL printer: one of its capabilities.speed_ips.","type":"number","exclusiveMinimum":0,"maximum":100}},"additionalProperties":false,"description":"Only what this job needs. Anything left out prints as the printer itself is set (PrinterDefaults)."},"JobReason":{"type":"object","properties":{"code":{"type":"string","description":"A stable code, for apps."},"message":{"type":"string","description":"What it means and what to do, in the language of the request."},"detail":{"description":"The printer's or the computer's own words.","type":["string","null"]},"since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["code","message","detail","since"],"additionalProperties":false},"JobSort":{"type":"string","enum":["-created_at","created_at","title","-title","state","-state","printer","-printer","app","-app"],"description":"A column, with a minus for the other way. -created_at, the newest first, by default. title, printer and app go by name as people read it, jobs without a title or an app last; state as a job goes, from queued to cancelled."},"JobState":{"type":"string","enum":["queued","claimed","spooled","printed","confirmed","failed","expired","cancelled"],"description":"queued: we have it, and it waits for its computer or its turn. claimed: its computer took it and prepares it. spooled: in the printer's queue in Windows. printed: the printer took all of it and reported no error; nobody has seen it yet. confirmed: a person said it came out right. failed: we know it did not print, or a person said it did not come out right. expired: it did not reach the printer in its time, and never will. cancelled: cancelled before it started to print."},"JobStateChangedWebhook":{"type":"object","properties":{"type":{"type":"string","const":"job.state_changed"},"timestamp":{"type":"string","format":"date-time","description":"When it changed."},"account_id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"changes":{"type":"array","items":{"type":"string"},"description":"Always state."},"data":{"anyOf":[{"$ref":"#/components/schemas/PrintJob"},{"$ref":"#/components/schemas/GoneSubject"}],"description":"The subject as it was: a job at the change the message tells of, a printer or a computer when the message first left. The same on every attempt."}},"required":["type","timestamp","account_id","changes","data"],"additionalProperties":false},"JobTimelineEntry":{"type":"object","properties":{"kind":{"type":"string","enum":["state","note"],"description":"note: something that did not change the state, e.g. a report after a person's word."},"state":{"$ref":"#/components/schemas/JobState"},"at":{"type":"string","format":"date-time"},"happened_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the computer says it happened."},"by":{"$ref":"#/components/schemas/ActorRef"},"reason":{"type":["string","null"]},"detail":{"type":["string","null"]}},"required":["kind","state","at","happened_at","by","reason","detail"],"additionalProperties":false},"JournalEntry":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"claim_id":{"type":"string","pattern":"^clm_[0-9a-z]{26}$"},"state":{"type":"string","enum":["queued","spooled","printed","failed","expired","cancelled"],"description":"queued: left before it was sent to the printer. printed: the printer took all of it without an error."},"reason":{"$ref":"#/components/schemas/AgentJobReason"},"detail":{"description":"The printer's or the computer's own words.","type":"string","maxLength":500},"at":{"description":"When it happened, by the computer's clock set to the server's.","type":"string","format":"date-time"}},"required":["job_id","claim_id","state"],"additionalProperties":false},"JournalResult":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"outcome":{"type":"string","enum":["applied","unchanged","stale","noted","unknown"],"description":"applied. unchanged: it already was so. stale: an older claim. noted: a person already decided, so the report only goes in the timeline. unknown: not a job of this computer."},"state":{"anyOf":[{"$ref":"#/components/schemas/JobState"},{"type":"null"}]}},"required":["job_id","outcome","state"],"additionalProperties":false}},"cancel":{"type":"array","items":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"description":"Jobs a person cancelled while this computer held them: take them out, and report."}},"required":["results","cancel"],"additionalProperties":false},"Locale":{"type":"string","enum":["el","en"],"description":"Greek or English."},"Location":{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-9a-z]{26}$"},"name":{"type":"string"},"kind":{"type":"string","enum":["place","home"],"description":"place: a place of the account, e.g. an office. home: a person's home: only that person sees what prints there."},"home_of":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}]},"time_zone":{"description":"Its own time zone (IANA), when it lies in another than the account's: its test pages say its time.","type":["string","null"]},"workstations":{"type":"integer","description":"How many workstations it has."},"computers":{"type":"integer","description":"How many computers are in it."},"printers":{"type":"integer","description":"How many printers are in it."},"created_at":{"type":"string","format":"date-time"}},"required":["id","name","kind","home_of","time_zone","workstations","computers","printers","created_at"],"additionalProperties":false,"description":"A place of the account: an office, a shop, a warehouse or a home."},"LocationList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Location"}}},"required":["data"],"additionalProperties":false},"Me":{"type":"object","properties":{"person":{"$ref":"#/components/schemas/Person"},"accounts":{"type":"array","items":{"$ref":"#/components/schemas/AccountMembership"}}},"required":["person","accounts"],"additionalProperties":false},"Member":{"type":"object","properties":{"person":{"$ref":"#/components/schemas/PersonRef"},"role":{"$ref":"#/components/schemas/Role"},"joined_at":{"type":"string","format":"date-time"}},"required":["person","role","joined_at"],"additionalProperties":false},"MemberList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"required":["data"],"additionalProperties":false},"NotCounted":{"type":"object","properties":{"virtual":{"type":"integer","description":"Jobs sent to the virtual printer, which prints nothing."},"test_pages":{"type":"integer","description":"Test pages sent to real printers."},"failed":{"type":"integer","description":"Jobs on real printers that failed without printing."},"cancelled":{"type":"integer","description":"Jobs on real printers cancelled before they printed."},"expired":{"type":"integer","description":"Jobs on real printers whose time ran out before they printed."}},"required":["virtual","test_pages","failed","cancelled","expired"],"additionalProperties":false,"description":"This month's jobs that the plan does not count, by why."},"Orientation":{"type":"string","enum":["auto","portrait","landscape"],"description":"auto: as the page fits the paper best. portrait or landscape: always so."},"PairedComputer":{"type":"object","properties":{"id":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"},"account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"workstation":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","account","location","workstation"],"additionalProperties":false,"description":"Where the computer is, as its program shows it."},"PairingApproved":{"type":"object","properties":{"computer":{"$ref":"#/components/schemas/Computer"},"reason":{"$ref":"#/components/schemas/PlacementReason"},"same_network_as":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The workstation of a computer on the same network, when that is the reason."}},"required":["computer","reason","same_network_as"],"additionalProperties":false},"PairingRequest":{"type":"object","properties":{"id":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"},"code":{"type":"string","description":"To compare with what the program shows."},"computer_name":{"type":"string"},"os":{"type":["string","null"]},"near":{"description":"Roughly where the request came from, e.g. a city.","type":["string","null"]},"requested_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}},"required":["id","code","computer_name","os","near","requested_at","expires_at"],"additionalProperties":false,"description":"A computer that asks to join the account."},"PairingStarted":{"type":"object","properties":{"id":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"},"code":{"type":"string","description":"8 characters in two groups, e.g. K7Q4-MX2P. It works once, for 10 minutes."},"expires_at":{"type":"string","format":"date-time"},"approve_url":{"type":"string","description":"Opens the app with the code filled in: for the QR and for «Open Printaloo»."}},"required":["id","code","expires_at","approve_url"],"additionalProperties":false},"PairingState":{"type":"object","properties":{"id":{"type":"string","pattern":"^pai_[0-9a-z]{26}$"},"status":{"type":"string","enum":["pending","approved","denied","expired"]},"expires_at":{"type":"string","format":"date-time"},"computer":{"anyOf":[{"$ref":"#/components/schemas/PairedComputer"},{"type":"null"}],"description":"Once approved."}},"required":["id","status","expires_at","computer"],"additionalProperties":false},"Paper":{"type":"object","properties":{"size":{"type":"string","description":"The name a job uses: A3, A4, A5, A6, Letter, Legal, Tabloid, or the size in mm, e.g. 100x150mm."},"name":{"type":"string","description":"What the printer's driver calls it."},"width_mm":{"type":"number"},"height_mm":{"type":"number"}},"required":["size","name","width_mm","height_mm"],"additionalProperties":false},"Person":{"type":"object","properties":{"id":{"type":"string","pattern":"^usr_[0-9a-z]{26}$"},"email":{"type":"string"},"name":{"type":["string","null"]},"locale":{"$ref":"#/components/schemas/Locale"}},"required":["id","email","name","locale"],"additionalProperties":false,"description":"A person, who may belong to several accounts."},"PersonRef":{"type":"object","properties":{"id":{"type":"string","pattern":"^usr_[0-9a-z]{26}$"},"email":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","email","name"],"additionalProperties":false},"PlacementReason":{"type":"string","enum":["first_computer","same_network","only_location","most_computers"],"description":"Why the computer went where it is: the first computer of the account; a computer on the same network is there; the account has only this location; or it has the most computers."},"Plan":{"type":"string","enum":["free","small","medium","large"],"description":"free: 500 printed jobs a month, then new jobs on real printers wait for the next month. small: 5,000. medium: 25,000. large: 200,000. A paid plan never stops: what it prints above its jobs is paid with the next month."},"PlanDay":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"A day of this month, in UTC."},"printed":{"type":"integer","description":"The jobs printed that day, as the plan counts them."}},"required":["date","printed"],"additionalProperties":false},"PlanLimit":{"type":"object","properties":{"stopped":{"type":"boolean","description":"Free, with the month's jobs used: new jobs on real printers are refused (plan_limit_reached) until resets_at."},"resets_at":{"type":"string","format":"date-time","description":"When the month's count starts again: the 1st of next month, 00:00 UTC."},"managers":{"type":"array","items":{"$ref":"#/components/schemas/PersonRef"},"description":"Who changes the plan: the Owner, then the Admins, by name."}},"required":["stopped","resets_at","managers"],"additionalProperties":false,"description":"Whether the account's new jobs wait for next month, for every member, and whom to ask: without the month's numbers, which only the Owner and the Admins see (AccountPlan)."},"PlanList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PlanOffer"}}},"required":["data"],"additionalProperties":false},"PlanOffer":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/Plan"},"jobs":{"type":"integer","description":"Printed jobs a month."},"price":{"type":"integer","description":"A month, in cents of the currency, without VAT: 700 is 7 €."},"extra_per_1000":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"What 1,000 printed jobs above the plan's cost, in cents without VAT: each job above it is paid with the next month. null on free, whose new jobs wait for the next month instead."},"currency":{"type":"string","description":"ISO 4217, e.g. EUR."}},"required":["plan","jobs","price","extra_per_1000","currency"],"additionalProperties":false,"description":"A plan an account may have. The app writes each amount as its language does: «7 €» in Greek, «€7» in English."},"PlanState":{"type":"string","enum":["ok","near","reached"],"description":"Of the plan's jobs, the month's printed and waiting ones: ok, under 80%. near: 80% or more. reached: all of them. At near and at reached the app tells the Owner and the Admins."},"Printer":{"type":"object","properties":{"id":{"type":"string","pattern":"^prn_[0-9a-z]{26}$"},"name":{"type":"string","description":"The name a person gave it, or else what Windows calls it."},"system_name":{"type":"string","description":"What Windows, or the printer itself, calls it."},"virtual":{"type":"boolean","description":"Printaloo's printer that does not print: it shows how a page would come out."},"kind":{"$ref":"#/components/schemas/PrinterKind"},"connection":{"$ref":"#/components/schemas/PrinterConnection"},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"driver":{"description":"Its driver, as Windows calls it. null for a printer reached without a driver.","type":["string","null"]},"port":{"description":"Its port, as Windows calls it, e.g. USB001, IP_192.168.1.40 or WSD-…. null when its program has not said it, and for a printer reached without a driver.","type":["string","null"]},"computer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"location":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"workstation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"null: shared by the whole location."},"with_computer":{"type":"boolean","description":"It goes wherever its computer goes, until a person places it."},"status":{"$ref":"#/components/schemas/PrinterStatus"},"reason":{"anyOf":[{"$ref":"#/components/schemas/PrinterReason"},{"type":"null"}],"description":"Why it is not ready."},"status_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"paused_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"paused_by":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["person","key","computer","app","system"]},"id":{"type":["string","null"]},"name":{"description":"The person's name, or the computer's or the key's.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false},{"type":"null"}],"description":"Who paused it: a person, an app with its API key, or someone at the computer, in the Printaloo program."},"hidden":{"type":"boolean","description":"Hidden from lists: Windows' own software printers start hidden."},"capabilities":{"$ref":"#/components/schemas/PrinterCapabilities"},"defaults":{"$ref":"#/components/schemas/PrinterDefaults"},"created_at":{"type":"string","format":"date-time"},"reported_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When its computer last reported it."}},"required":["id","name","system_name","virtual","kind","connection","make","model","driver","port","computer","location","workstation","with_computer","status","reason","status_since","paused_at","paused_by","hidden","capabilities","defaults","created_at","reported_at"],"additionalProperties":false,"description":"A printer of the account, with what it can do and how it is now."},"PrinterCapabilities":{"type":"object","properties":{"papers":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Paper"}},{"type":"null"}],"description":"Every paper or label size it prints on."},"dpi":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}]},"zpl":{"description":"Whether it takes ZPL: a Zebra, or a printer that passed a ZPL test label.","type":["boolean","null"]},"duplex":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Duplex"}},{"type":"null"}]},"color":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ColorMode"}},{"type":"null"}]},"trays":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Tray"}},{"type":"null"}],"description":"Its paper trays. A job names one by id, and only with printer_id."},"darkness":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The darkness values of a label printer, on its own scale, e.g. 0 to 30."},"speed_ips":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The speeds of a label printer, in inches per second."}},"required":["papers","dpi","zpl","duplex","color","trays","darkness","speed_ips"],"additionalProperties":false,"description":"What the printer can do, as its computer read it. null: not known yet; a job is accepted, and the computer checks again before it prints. A list: what it supports, [] when it has none."},"PrinterConnection":{"type":"string","enum":["usb","network","shared","direct","software","other","virtual"],"description":"usb. network: installed in Windows by its address. shared: shared by another computer. direct: reached by the program on the network, without a driver (IPP, or port 9100 for labels). software: a Windows printer that makes a file, e.g. Microsoft Print to PDF. other: a serial or parallel port. virtual: Printaloo's printer that does not print."},"PrinterDefaults":{"type":"object","properties":{"paper_size":{"description":"A document printer's size for a job that does not say.","type":["string","null"]},"label_size":{"description":"A label printer's size for a job that does not say.","type":["string","null"]},"scaling":{"$ref":"#/components/schemas/Scaling"},"duplex":{"anyOf":[{"$ref":"#/components/schemas/Duplex"},{"type":"null"}]},"color":{"anyOf":[{"$ref":"#/components/schemas/ColorMode"},{"type":"null"}]},"tray":{"type":["string","null"]},"darkness":{"type":["number","null"]},"speed_ips":{"type":["number","null"]}},"required":["paper_size","label_size","scaling","duplex","color","tray","darkness","speed_ips"],"additionalProperties":false,"description":"What a job gets when it does not ask. paper_size or label_size, and scaling, are Printaloo's, and change here. duplex, color, tray, darkness and speed_ips are the printer's own settings: they change only on the printer, and are null while not known."},"PrinterKind":{"type":"string","enum":["document","label"],"description":"document: pages such as A4. label: labels such as 100x150mm."},"PrinterList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Printer"}}},"required":["data"],"additionalProperties":false},"PrinterProbe":{"type":"object","properties":{"id":{"type":"string","pattern":"^prb_[0-9a-z]{26}$"},"address":{"type":"string"},"computer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"state":{"type":"string","enum":["testing","found","no_answer","not_a_printer","computer_offline","timed_out"],"description":"testing. found: a printer answered. no_answer: nothing answered at that address. not_a_printer: something answered, but not a printer. computer_offline: the computer went offline before it answered. timed_out: it did not answer in time."},"detail":{"description":"What the computer saw, in its own words, e.g. «connection refused».","type":["string","null"]},"found_printer":{"anyOf":[{"$ref":"#/components/schemas/FoundPrinter"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"}},"required":["id","address","computer","state","detail","found_printer","created_at"],"additionalProperties":false,"description":"A computer tests an address before a printer goes in by hand. Read it every second."},"PrinterProblem":{"type":"string","enum":["paper_out","paper_jam","door_open","supply_out","paused_in_windows","other"],"description":"supply_out: ink, toner or ribbon. paused_in_windows: someone paused it in Windows. other: see the printer's own words."},"PrinterReason":{"type":"object","properties":{"code":{"type":"string","enum":["computer_offline","computer_removed","not_found","paused","printer_offline","paper_out","paper_jam","door_open","supply_out","paused_in_windows","other"]},"message":{"type":"string","description":"What is wrong and what to do, in the language of the request."},"detail":{"description":"The printer's own words, as it said them.","type":["string","null"]}},"required":["code","message","detail"],"additionalProperties":false},"PrinterSearch":{"type":"object","properties":{"id":{"type":"string","pattern":"^srh_[0-9a-z]{26}$"},"location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"state":{"type":"string","enum":["searching","done"],"description":"done: every computer it asked has searched, or its time is up."},"started_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"computers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^cmp_[0-9a-z]{26}$"},"name":{"type":"string"},"state":{"type":"string","enum":["searching","done","offline"]}},"required":["id","name","state"],"additionalProperties":false},"description":"The computers of the location that were online when it started."},"found":{"type":"array","items":{"$ref":"#/components/schemas/FoundPrinter"},"description":"What its computers saw since it started, the first seen first."},"probe_computer":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The computer that would test an address typed by hand now (D14b)."}},"required":["id","location","state","started_at","ends_at","computers","found","probe_computer"],"additionalProperties":false,"description":"The computers of a location search their network for printers, for a few seconds. Read it every second."},"PrinterStatus":{"type":"string","enum":["ready","paused","offline","error","not_found"],"description":"ready. paused: in Printaloo, its jobs wait. offline: it, or its computer, does not answer. error: it says what is wrong. not_found: its computer no longer finds it, or the computer was removed; a person says which printer it is now."},"PrinterUpdatedWebhook":{"type":"object","properties":{"type":{"type":"string","const":"printer.updated"},"timestamp":{"type":"string","format":"date-time","description":"When it changed."},"account_id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"changes":{"type":"array","items":{"type":"string"},"description":"What changed, e.g. added, status, capabilities, defaults, name, placement, paused, removed."},"data":{"anyOf":[{"$ref":"#/components/schemas/Printer"},{"$ref":"#/components/schemas/GoneSubject"}],"description":"The subject as it was: a job at the change the message tells of, a printer or a computer when the message first left. The same on every attempt."}},"required":["type","timestamp","account_id","changes","data"],"additionalProperties":false},"PrintJob":{"type":"object","properties":{"id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"state":{"$ref":"#/components/schemas/JobState"},"sequence":{"type":"integer","description":"One more with every change: keep the highest you have seen."},"waiting_reason":{"anyOf":[{"$ref":"#/components/schemas/JobReason"},{"type":"null"}],"description":"What holds it while it waits or prints, e.g. its computer is offline."},"reason":{"anyOf":[{"$ref":"#/components/schemas/JobReason"},{"type":"null"}],"description":"Why it failed, expired or was cancelled."},"printer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"workstation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"app":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The app that sent it, by its API key: the id stays the same across rotations, the name is its newest key's. Null when a person or a computer's program sent it from Printaloo."},"content_type":{"$ref":"#/components/schemas/ContentType"},"paper_size":{"type":["string","null"]},"label_size":{"type":["string","null"]},"scaling":{"$ref":"#/components/schemas/Scaling"},"orientation":{"$ref":"#/components/schemas/Orientation"},"copies":{"type":"integer"},"options":{"$ref":"#/components/schemas/JobOptions"},"from_page":{"anyOf":[{"type":"integer"},{"type":"null"}]},"title":{"type":["string","null"]},"reference":{"type":["string","null"]},"file":{"$ref":"#/components/schemas/JobFile"},"sent_by":{"$ref":"#/components/schemas/ActorRef"},"decided_by":{"anyOf":[{"$ref":"#/components/schemas/ActorRef"},{"type":"null"}],"description":"The person who said it came out right, or did not."},"reprint_of":{"anyOf":[{"type":"string","pattern":"^job_[0-9a-z]{26}$"},{"type":"null"}]},"cancel_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Cancelled while its computer had it: the computer takes it out."},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","state","sequence","waiting_reason","reason","printer","workstation","app","content_type","paper_size","label_size","scaling","orientation","copies","options","from_page","title","reference","file","sent_by","decided_by","reprint_of","cancel_requested_at","expires_at","created_at","updated_at"],"additionalProperties":false,"description":"One paper an app wants: a file, for a printer, with its settings and its state."},"PrintJobDetail":{"type":"object","properties":{"id":{"type":"string","pattern":"^job_[0-9a-z]{26}$"},"state":{"$ref":"#/components/schemas/JobState"},"sequence":{"type":"integer","description":"One more with every change: keep the highest you have seen."},"waiting_reason":{"anyOf":[{"$ref":"#/components/schemas/JobReason"},{"type":"null"}],"description":"What holds it while it waits or prints, e.g. its computer is offline."},"reason":{"anyOf":[{"$ref":"#/components/schemas/JobReason"},{"type":"null"}],"description":"Why it failed, expired or was cancelled."},"printer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"workstation":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"app":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The app that sent it, by its API key: the id stays the same across rotations, the name is its newest key's. Null when a person or a computer's program sent it from Printaloo."},"content_type":{"$ref":"#/components/schemas/ContentType"},"paper_size":{"type":["string","null"]},"label_size":{"type":["string","null"]},"scaling":{"$ref":"#/components/schemas/Scaling"},"orientation":{"$ref":"#/components/schemas/Orientation"},"copies":{"type":"integer"},"options":{"$ref":"#/components/schemas/JobOptions"},"from_page":{"anyOf":[{"type":"integer"},{"type":"null"}]},"title":{"type":["string","null"]},"reference":{"type":["string","null"]},"file":{"$ref":"#/components/schemas/JobFile"},"sent_by":{"$ref":"#/components/schemas/ActorRef"},"decided_by":{"anyOf":[{"$ref":"#/components/schemas/ActorRef"},{"type":"null"}],"description":"The person who said it came out right, or did not."},"reprint_of":{"anyOf":[{"type":"string","pattern":"^job_[0-9a-z]{26}$"},{"type":"null"}]},"cancel_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Cancelled while its computer had it: the computer takes it out."},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"timeline":{"type":"array","items":{"$ref":"#/components/schemas/JobTimelineEntry"}}},"required":["id","state","sequence","waiting_reason","reason","printer","workstation","app","content_type","paper_size","label_size","scaling","orientation","copies","options","from_page","title","reference","file","sent_by","decided_by","reprint_of","cancel_requested_at","expires_at","created_at","updated_at","timeline"],"additionalProperties":false},"PrintJobList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PrintJob"}},"next_cursor":{"description":"For the next page, as `cursor`; null on the last page, and with offset.","type":["string","null"]},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many jobs match, for a page asked with offset; null with a cursor."}},"required":["data","next_cursor","total"],"additionalProperties":false},"PrintJobsToday":{"type":"object","properties":{"day":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"Today, in the account's time zone."},"time_zone":{"type":"string","description":"The account's time zone, where its day starts."},"needs_person":{"type":"object","properties":{"count":{"type":"integer","description":"The jobs that need a person now: what GET /v1/print-jobs finds with needs_person=true."},"by_reason":{"type":"array","items":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/AttentionCode"},"count":{"type":"integer"}},"required":["code","count"],"additionalProperties":false},"description":"What they need, the most first, e.g. 2 paper_out, 1 failed, 1 unknown."}},"required":["count","by_reason"],"additionalProperties":false},"sent":{"type":"integer","description":"The jobs sent today: what GET /v1/print-jobs finds with day=today."},"sent_by_hour":{"type":"array","items":{"type":"integer"},"description":"The jobs sent in each hour of today so far: the first from 00:00, the last the hour now."},"printed":{"type":"integer","description":"Of today's jobs, those a printer printed (printed or confirmed)."},"confirmed":{"type":"integer","description":"Of today's jobs, those a person said came out right."}},"required":["day","time_zone","needs_person","sent","sent_by_hour","printed","confirmed"],"additionalProperties":false,"description":"The day's numbers of the jobs the caller sees. Today is the account's: GET /v1/account, time_zone."},"PrintJobView":{"type":"object","properties":{"id":{"type":"string","pattern":"^viw_[0-9a-z]{26}$"},"name":{"type":"string"},"filters":{"type":"object","properties":{"q":{"description":"Words in the title or the reference.","type":"string","minLength":1,"maxLength":100},"state":{"description":"One state, or several separated by commas. unknown: nobody knows whether it printed, because its computer went silent while it had it, or started again in the middle of sending it; claimed or spooled finds these too. not_ok: failed because a person said it did not come out right; failed finds these too.","type":"string"},"shown_as":{"description":"As state, but each value finds exactly the jobs that a list shows with its word, as Printaloo's app does: failed leaves out not_ok, and claimed and spooled leave out unknown.","type":"string"},"needs_person":{"description":"Only the jobs that need a person now, as GET /v1/print-jobs/today counts them.","type":"string","const":"true"},"printer_id":{"description":"One printer's jobs, or several printers' separated by commas.","type":"string"},"workstation_id":{"description":"The jobs sent to this workstation.","type":"string","pattern":"^wks_[0-9a-z]{26}$"},"app_id":{"description":"One app's jobs, or several apps' separated by commas: the ids of GET /v1/apps. printaloo: what Printaloo itself sent for a person, from its web app or from the program on a computer (app null).","type":"string"},"day":{"description":"In the account's time zone: today; yesterday; last_7_days or last_30_days, today and the days before it, which move on with the days in a saved view; or a date such as 2026-10-21.","anyOf":[{"type":"string","enum":["today","yesterday","last_7_days","last_30_days"]},{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}]},"created_after":{"description":"Made at or after this moment.","type":"string","format":"date-time"},"created_before":{"description":"Made before this moment.","type":"string","format":"date-time"},"reference":{"description":"Exactly this reference, e.g. an order number.","type":"string","minLength":1,"maxLength":200},"sort":{"description":"The order: -created_at, the newest first, by default.","$ref":"#/components/schemas/JobSort"}},"additionalProperties":false,"description":"GET /v1/print-jobs with these shows the view."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","filters","created_at","updated_at"],"additionalProperties":false,"description":"«Αποθήκευση προβολής»: a list of jobs a person keeps by name. Only they see it."},"PrintJobViewList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PrintJobView"}}},"required":["data"],"additionalProperties":false},"Problem":{"type":"object","properties":{"type":{"type":"string","description":"A URI for this kind of problem."},"title":{"type":"string","description":"A short summary of this kind of problem."},"status":{"type":"integer","description":"The HTTP status code."},"detail":{"type":"string","description":"What happened and how to fix it, in plain words."},"instance":{"type":"string","description":"The id of this request, for support."},"code":{"type":"string","description":"A stable code for this kind of problem."},"errors":{"type":"array","items":{"$ref":"#/components/schemas/FieldError"}},"option":{"description":"With unsupported_option: the setting, e.g. `duplex`.","type":"string"},"value":{"description":"With unsupported_option: the value that was asked."},"supported":{"description":"With unsupported_option: what the printer supports.","type":"array","items":{}},"account_id":{"description":"With account_key_conflict: the account that the key made.","type":"string"},"plan":{"description":"With plan_limit_reached: the account's plan, free.","type":"string"},"limit":{"description":"With plan_limit_reached: the plan's printed jobs in a month.","type":"integer"},"resets_at":{"description":"With plan_limit_reached: when new jobs come again, the 1st of next month in UTC.","type":"string"},"attempts_left":{"description":"With invalid_code: the wrong tries the code still takes.","type":"integer"},"retry_after":{"description":"With too_many_codes: seconds until another code may be sent.","type":"integer"}},"required":["type","title","status","detail","instance","code"],"additionalProperties":false,"description":"An error, as RFC 9457 problem details (application/problem+json)."},"ResentWebhookMessages":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookMessage"},"description":"The messages, due now: each shows how it went, as it goes."}},"required":["data"],"additionalProperties":false},"Role":{"type":"string","enum":["owner","admin","operator"],"description":"owner: everything, with deleting the account. admin: everything but deleting the account and changing the owner. operator: sees computers, printers and jobs, prints test pages, confirms and reprints, pauses printers and cancels what waits."},"RotatedApiKey":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","description":"The new key itself, shown only now."},"previous":{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[0-9a-z]{26}$"},"works_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The old key works until then; null when it stopped at once."}},"required":["id","works_until"],"additionalProperties":false}},"required":["key","secret","previous"],"additionalProperties":false},"Scaling":{"type":"string","enum":["actual_size","shrink_to_fit"],"description":"actual_size: as the file is. shrink_to_fit: as the file is, and smaller only when the page does not fit; never larger."},"Session":{"type":"object","properties":{"id":{"type":"string","pattern":"^ses_[0-9a-z]{26}$"},"method":{"type":"string","enum":["local","oidc"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}},"required":["id","method","created_at","expires_at"],"additionalProperties":false},"SessionTransfer":{"type":"object","properties":{"url":{"type":"string","description":"The app's page that signs in with it, then opens the path asked for."},"expires_at":{"type":"string","format":"date-time","description":"A minute from now: it works once, before then."}},"required":["url","expires_at"],"additionalProperties":false},"SignedIn":{"type":"object","properties":{"token":{"type":"string","description":"Shown only now: the bearer token of this session."},"session":{"$ref":"#/components/schemas/Session"},"person":{"$ref":"#/components/schemas/Person"},"new_account":{"type":"boolean","description":"The code finished a sign-up: the person is new. Their accounts are in GET /v1/me."}},"required":["token","session","person","new_account"],"additionalProperties":false},"SizeName":{"type":"string","pattern":"^(A3|A4|A5|A6|Letter|Legal|Tabloid|\\d{1,4}(\\.\\d)?x\\d{1,5}(\\.\\d)?mm)$"},"Tray":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"UsageList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UsageMonth"},"description":"This month first, back to the month the account began."}},"required":["data"],"additionalProperties":false},"UsageMonth":{"type":"object","properties":{"month":{"type":"string","description":"A month in UTC, e.g. 2026-10."},"jobs":{"type":"integer","description":"Jobs sent to the account's printers: by apps, by people, test pages and reprints."},"printed_jobs":{"type":"integer","description":"Jobs that reached a printer, once each, without test pages: what the plan counts (PRODUCT §4.10)."},"pages":{"type":"integer","description":"Their pages: a PDF's pages or a ZPL file's labels, times the copies."},"computers":{"type":"integer","description":"Computers that connected in the month."},"virtual_jobs":{"type":"integer","description":"Jobs sent to the virtual printer, which prints nothing: not in the numbers above."}},"required":["month","jobs","printed_jobs","pages","computers","virtual_jobs"],"additionalProperties":false,"description":"An account's usage in one month."},"Webhook":{"type":"object","properties":{"id":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"status":{"$ref":"#/components/schemas/WebhookStatus"},"failing_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Since when every attempt has failed; null while it answers."},"last_attempt":{"anyOf":[{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The endpoint's answer; null when there was none."},"error":{"description":"Why there was no answer, e.g. no answer in 15 seconds.","type":["string","null"]}},"required":["at","status_code","error"],"additionalProperties":false},{"type":"null"}],"description":"The endpoint's last attempt, of any message, and what it answered: while it fails, why."},"paused_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When a person paused it, while it is paused."},"paused_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}],"description":"Who paused it, while it is paused; null when an API key did."},"previous_secret_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"After a rotation, the old secret signs too until then."},"created_at":{"type":"string","format":"date-time"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/PersonRef"},{"type":"null"}],"description":"Who made it; null when an API key did."},"updated_at":{"type":"string","format":"date-time"}},"required":["id","url","description","events","status","failing_since","last_attempt","paused_at","paused_by","previous_secret_until","created_at","created_by","updated_at"],"additionalProperties":false,"description":"An endpoint of the account, and the events it hears."},"WebhookAttempt":{"type":"object","properties":{"number":{"type":"integer","description":"1 for the first."},"at":{"type":"string","format":"date-time"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The endpoint's answer; null when there was none."},"error":{"description":"Why there was no answer, e.g. no answer in 15 seconds, could not connect, a private address.","type":["string","null"]},"duration_ms":{"type":"integer"}},"required":["number","at","status_code","error","duration_ms"],"additionalProperties":false,"description":"One attempt to send a message."},"WebhookAttemptDetail":{"type":"object","properties":{"number":{"type":"integer","description":"1 for the first."},"at":{"type":"string","format":"date-time"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The endpoint's answer; null when there was none."},"error":{"description":"Why there was no answer, e.g. no answer in 15 seconds, could not connect, a private address.","type":["string","null"]},"duration_ms":{"type":"integer"},"response":{"description":"The first 2,000 characters of the endpoint's answer.","type":["string","null"]}},"required":["number","at","status_code","error","duration_ms","response"],"additionalProperties":false,"description":"One attempt to send a message, with the endpoint's answer."},"WebhookEventType":{"type":"string","enum":["job.state_changed","printer.updated","computer.updated"],"description":"job.state_changed: a job's state changed; keep the highest sequence, as two may arrive in the other order. printer.updated: its status, capabilities or place changed, or it was removed. computer.updated: online, offline, moved or removed."},"WebhookList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["data"],"additionalProperties":false},"WebhookMessage":{"type":"object","properties":{"id":{"type":"string","pattern":"^msg_[0-9a-z]{26}$","description":"The webhook-id header: the same on every attempt."},"webhook_id":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"},"type":{"type":"string","enum":["job.state_changed","printer.updated","computer.updated","webhook.test"]},"subject_id":{"description":"What it is about: a job, a printer, a computer, or the webhook for a test.","type":["string","null"]},"subject":{"type":"object","properties":{"name":{"description":"What people call it: a job's title or reference, a printer's or a computer's name, the webhook's for a test. null when it is gone, or for a job at another person's home, which only they see.","type":["string","null"]},"state":{"anyOf":[{"$ref":"#/components/schemas/JobState"},{"type":"null"}],"description":"For job.state_changed: the state the message tells of."},"status":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/PrinterStatus"},{"type":"string","enum":["online","offline"]}]},{"type":"null"}],"description":"For printer.updated, the printer's status the message tells of; for computer.updated, online or offline. null when the message has not left yet, or its subject was gone when it did."},"reason":{"description":"For job.state_changed, why at that moment, as the job's codes say it: what held one that waited (paper_out, computer_offline…, as waiting_reason), or why one ended (not_ok, not_in_time…, as reason). A job waiting for paper is state queued and reason paper_out. For printer.updated, why the printer was not ready, as its reason.code: a label printer out of labels is status error, reason paper_out and kind label.","type":["string","null"]},"kind":{"anyOf":[{"$ref":"#/components/schemas/PrinterKind"},{"type":"null"}],"description":"For printer.updated: a document or a label printer, as the message tells."}},"required":["name","state","status","reason","kind"],"additionalProperties":false,"description":"What the message is about, as it told it: its subject's name, state or status, and why."},"changes":{"type":"array","items":{"type":"string"},"description":"What changed, as the message says it, e.g. state, status, added."},"status":{"$ref":"#/components/schemas/WebhookMessageStatus"},"attempt_count":{"type":"integer"},"last_attempt":{"anyOf":[{"$ref":"#/components/schemas/WebhookAttempt"},{"type":"null"}]},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it goes again, while it is pending."},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When an attempt was last answered with 2xx."},"created_at":{"type":"string","format":"date-time"}},"required":["id","webhook_id","type","subject_id","subject","changes","status","attempt_count","last_attempt","next_attempt_at","delivered_at","created_at"],"additionalProperties":false,"description":"One message to a webhook. It stays 30 days, with its attempts."},"WebhookMessageDetail":{"type":"object","properties":{"id":{"type":"string","pattern":"^msg_[0-9a-z]{26}$","description":"The webhook-id header: the same on every attempt."},"webhook_id":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"},"type":{"type":"string","enum":["job.state_changed","printer.updated","computer.updated","webhook.test"]},"subject_id":{"description":"What it is about: a job, a printer, a computer, or the webhook for a test.","type":["string","null"]},"subject":{"type":"object","properties":{"name":{"description":"What people call it: a job's title or reference, a printer's or a computer's name, the webhook's for a test. null when it is gone, or for a job at another person's home, which only they see.","type":["string","null"]},"state":{"anyOf":[{"$ref":"#/components/schemas/JobState"},{"type":"null"}],"description":"For job.state_changed: the state the message tells of."},"status":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/PrinterStatus"},{"type":"string","enum":["online","offline"]}]},{"type":"null"}],"description":"For printer.updated, the printer's status the message tells of; for computer.updated, online or offline. null when the message has not left yet, or its subject was gone when it did."},"reason":{"description":"For job.state_changed, why at that moment, as the job's codes say it: what held one that waited (paper_out, computer_offline…, as waiting_reason), or why one ended (not_ok, not_in_time…, as reason). A job waiting for paper is state queued and reason paper_out. For printer.updated, why the printer was not ready, as its reason.code: a label printer out of labels is status error, reason paper_out and kind label.","type":["string","null"]},"kind":{"anyOf":[{"$ref":"#/components/schemas/PrinterKind"},{"type":"null"}],"description":"For printer.updated: a document or a label printer, as the message tells."}},"required":["name","state","status","reason","kind"],"additionalProperties":false,"description":"What the message is about, as it told it: its subject's name, state or status, and why."},"changes":{"type":"array","items":{"type":"string"},"description":"What changed, as the message says it, e.g. state, status, added."},"status":{"$ref":"#/components/schemas/WebhookMessageStatus"},"attempt_count":{"type":"integer"},"last_attempt":{"anyOf":[{"$ref":"#/components/schemas/WebhookAttempt"},{"type":"null"}]},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When it goes again, while it is pending."},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When an attempt was last answered with 2xx."},"created_at":{"type":"string","format":"date-time"},"body":{"description":"The JSON exactly as it was signed and sent; null before its first attempt, or for a job at another person's home.","type":["string","null"]},"attempts":{"type":"array","items":{"$ref":"#/components/schemas/WebhookAttemptDetail"}}},"required":["id","webhook_id","type","subject_id","subject","changes","status","attempt_count","last_attempt","next_attempt_at","delivered_at","created_at","body","attempts"],"additionalProperties":false,"description":"One message to a webhook, with what it sent and every answer."},"WebhookMessageList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookMessage"}},"next_cursor":{"description":"For the next page, as `cursor`; null on the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"WebhookMessageStatus":{"type":"string","enum":["pending","delivered","failed"],"description":"pending: it waits for its next attempt. delivered: an attempt was answered with 2xx, and it stays delivered. failed: no attempt was, and none is left."},"WebhookSecret":{"type":"object","properties":{"secret":{"type":"string","description":"whsec_ and the key, in base64. Keep it like a password."},"previous_secret_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["secret","previous_secret_until"],"additionalProperties":false},"WebhookStatus":{"type":"string","enum":["active","paused","disabled"],"description":"paused: by a person. disabled: it failed for 3 days in a row; a person turns it on again."},"WebhookTestSubject":{"type":"object","properties":{"id":{"type":"string","pattern":"^whk_[0-9a-z]{26}$"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"status":{"$ref":"#/components/schemas/WebhookStatus"},"failing_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Since when every attempt has failed; null while it answers."},"last_attempt":{"anyOf":[{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The endpoint's answer; null when there was none."},"error":{"description":"Why there was no answer, e.g. no answer in 15 seconds.","type":["string","null"]}},"required":["at","status_code","error"],"additionalProperties":false},{"type":"null"}],"description":"The endpoint's last attempt, of any message, and what it answered: while it fails, why."},"paused_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When a person paused it, while it is paused."},"previous_secret_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"After a rotation, the old secret signs too until then."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","url","description","events","status","failing_since","last_attempt","paused_at","previous_secret_until","created_at","updated_at"],"additionalProperties":false},"WebhookTestWebhook":{"type":"object","properties":{"type":{"type":"string","const":"webhook.test"},"timestamp":{"type":"string","format":"date-time","description":"When it changed."},"account_id":{"type":"string","pattern":"^acc_[0-9a-z]{26}$"},"changes":{"type":"array","items":{"type":"string"},"description":"Always empty."},"data":{"description":"The subject as it was: a job at the change the message tells of, a printer or a computer when the message first left. The same on every attempt.","$ref":"#/components/schemas/WebhookTestSubject"}},"required":["type","timestamp","account_id","changes","data"],"additionalProperties":false},"Workstation":{"type":"object","properties":{"id":{"type":"string","pattern":"^wks_[0-9a-z]{26}$"},"name":{"type":"string"},"location":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"computers":{"type":"integer","description":"How many computers are at it."},"printers":{"type":"integer","description":"How many printers are at it; a shared printer counts only in its location."},"created_at":{"type":"string","format":"date-time"}},"required":["id","name","location","computers","printers","created_at"],"additionalProperties":false,"description":"A spot in a location where someone works, e.g. Accounting or Shipping."},"WorkstationList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Workstation"}}},"required":["data"],"additionalProperties":false}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key of the account: `Authorization: Bearer pl_…`."},"session":{"type":"http","scheme":"bearer","description":"A signed-in person, for the app and the program: the access token of Printaloo's Meteorack Auth Sign-in, a JWT that this API checks alone (FMB-5412). Only in local and test, also this API's own session, `pls_…`."},"computer":{"type":"apiKey","in":"header","name":"Authorization","description":"A computer with the Printaloo program signs each request with its own Ed25519 key."}}}}