Make a magazine with your AI.
Use the origin of this page as SITE. Check your tools before starting: reading a website does not provide upload access. If you can create files but cannot publish, give the user a magazine ZIP to upload at SITE/desk?upload=1. A PDF alone is not accepted. Service review happens after upload; reading these instructions does not mean an issue has been checked, published, purchased, or ordered.
This page includes the complete instructions and API reference. No script, Markdown reader, account, or installation is required to read it.
Plain-text guideDownload instructions for your chatMarkdown skillInstallable skill ZIP
MyMagazine API v1
Base: the origin hosting this skill. JSON request/response bodies unless specified. Credentials use Authorization: Bearer TOKEN. Errors are { "error": { "code": "...", "message": "..." } }, sometimes with validation details. Do not log bearer tokens or reader URLs in shared logs.
Capabilities and creation
GET /v1/capabilities: limits, profiles, backend, schema, sample and skill URLs. instructionsUrl is the complete HTML guide at /start; instructionsTextUrl is its plain-text counterpart at /start.txt. publishRestricted is false: anyone can create an issue. The displayed profile is experimental until its qualification flag is enabled by the operator.
POST /v1/issues, with {title, description?}. No authorization header, invitation code, or account is required. The existing per-IP limit is 20 creation attempts per hour. Returns 201 {id, ownerToken, readToken, issueUrl, manageUrl}. New issues have sharing disabled; issueUrl is a reserved reading URL, not the user handoff. manageUrl is the clean private review page, requiring browser review access or existing owner access. Create a private review link below. Store immediately. Tokens are returned once. The service stores their hashes. Legacy upload browsers store owner credentials locally. The normal agent-to-user handoff uses a separate scoped, HttpOnly browser cookie; it never copies the owner token into the user’s browser.
Authenticate again for an existing issue
Read site, id, and ownerToken from the saved private editing file. Send GET /v1/issues/{id} to that same site with Authorization: Bearer OWNER_TOKEN. This verifies access and returns the current revision. Use that revision ID and the same bearer token for a new upload. A fresh agent session needs no cookies or publishing code. The Python helper performs these steps each time it runs with the same --state file; a browser-exported editing file also works.
Owner tokens do not have a scheduled expiry. Expired preview URLs can be refreshed by fetching owner status; an expired upload requires a new upload declaration. An unauthorized request must not trigger creation of a replacement magazine. Reader tokens, retired invitation codes, and other issues' owner tokens grant no editing access. If the editing file is lost, recover it from a browser that still has owner access or a private backup; there is no account-based credential recovery yet.
Private user review handoff
POST /v1/issues/{id}/review-links, owner bearer only, returns 201 {reviewUrl,expiresAt}. The URL is /review/{id}#access=ONE_USE_TOKEN, expires after 24 hours, and is for the user alone. This endpoint does not upload, approve, share, or order. Create a fresh link for a different browser or an expired/consumed handoff. Never grant access using a reading token. The Python helper creates a link after uploading; --review-link --site SITE --state PRIVATE_FILE creates one without an upload. --status remains strictly read-only.
The page POSTs {issueId,token} to /v1/review-access/redeem, requiring the same application Origin. The token is consumed atomically and establishes a host-only HttpOnly, SameSite=Strict cookie (Secure on HTTPS), scoped to this magazine for 30 days. Only token hashes are stored. The URL fragment is removed from browser history. Repeating redemption in the same session is safe; another browser cannot reuse it. Agents must not open or redeem links intended for their users.
Browser review cookies authorize GET /v1/issues/{id}, edition /identity, /accept-warnings, /approve, /share-link, /sharing, and /checkout. Cookie-authenticated writes require the same application Origin. They do not authorize uploads, source ZIP downloads, review retries, creating other review links, or any other magazine. Owner bearer access retains those authoring capabilities. Reading tokens authorize neither role. Exact-proof, warning, and purchase gates remain enforced for both authorized roles.
Uploads and revisions
GET /v1/issues/{id}, owner bearer or browser review access: state, current revision, latest prepared edition of that revision, owner proof URLs, report, printReadiness, revision history, purchase availability, access (owner, review, or reader), and sharingEnabled. Fetch this when the user asks to look at issues; copied feedback is not required. revisionId on owner/review status is always the current upload revision, even while the page displays the previous proof. revisionNumber identifies the displayed proof, latestRevisionNumber identifies the current revision, and pendingRevision is null or {revisionNumber,state,stage,updatedAt}. It reports a queued/running/interrupted review or a newer edition blocked by incomplete or failed checks, without exposing its private findings to readers. While processing, the previous proof can remain visible with an explicit progress notice. Signed owner previews expire; fetch status again for fresh links. The helper's --status --site SITE --state PRIVATE_FILE reads without uploading; --wait also polls ongoing review.
POST /v1/issues/{id}/uploads, owner bearer:
{
"parentRevisionId": null,
"manifest": {
"schemaVersion": "1",
"title": "Example",
"language": "en",
"entrypoints": { "print": "index.html" },
"profileId": "prodigi-a4-portrait"
},
"files": [
{
"path": "index.html",
"type": "text/html",
"size": 1234,
"sha256": "64-lowercase-hex-characters"
}
]
}
parentRevisionId must match the current owner response (null initially). The file list excludes magazine.json, which is represented by manifest. Returns 201 {uploadId, files:[{path,url,method}], finalizeUrl}. Uploads expire after 60 minutes. A 409 revision conflict means another upload won; fetch owner status before intentionally creating another revision. Creating a new upload is not an idempotent operation.
manifest.reader is optional. Omitted means the standard PDF-based reader, including on existing editions. {mode:"standard",layout?:"single"|"spread",navigation?:"paged"|"scroll",background?:"#RRGGBB",contents?:[{title,page}]} customizes it. Defaults are spreads, paged navigation, and a neutral background. Contents have at most 100 entries, titles up to 120 characters, and integer physical page numbers 1–100; entries beyond the actual PDF are omitted from the display. The print entrypoint is required; the web entrypoint is optional. {mode:"custom"} explicitly uses the web entrypoint and requires it. All entrypoints still undergo static-package validation. Browser scripts/forms and revision-editing controls remain unsupported. See the skill's reading-experience guidance before choosing custom mode.
Owner, private-review, and reading responses include resolved reader settings from the displayed edition. proofUrl is the authoritative document used by the standard reader; pages are lower-resolution preview images. contentUrl is nullable when no web entrypoint was supplied. A custom view uses contentUrl. A pending revision does not change the previous edition's reader settings. Capabilities expose supported reader modes/options.
PUT /v1/uploads/{uploadId}/files/{path}, owner bearer, raw bytes and declared Content-Type. Repeating the same bytes while the upload is open is safe. Declared path, hash, and size are enforced. No new files may be added after declaration.
POST /v1/uploads/{uploadId}/finalize, owner bearer. Checks the entire package, seals immutable source, and queues review. Safe to retry. Returns 202 on first finalization and 200 with the existing state on a repeated call. A 422 includes actionable package diagnostics. Change the package and create a new upload after a validation error; the old declared inventory cannot be edited.
POST /v1/issues/{id}/retry, owner bearer, retries a failed job up to the service's attempt limit. It does not remove review findings; content corrections require a new revision.
GET /v1/issues/{id}/source/{revisionId}, owner bearer, returns the original ZIP.
File URL imports
POST /v1/issues/{id}/imports is an alternative to declaring an inventory and uploading each file. It downloads a source ZIP immediately, validates it, stores immutable source, and queues the same rendering and print review. It does not approve, share, purchase, or place a print order. Discover current settings in GET /v1/capabilities.fileUrlImport; uploadMethods includes file-url.
For a new magazine, prepare the source ZIP and its download URL first, call POST /v1/issues, and securely save the returned issue ID and owner token before importing. For revisions, reuse that issue and its saved owner token. Fetch owner status for the current revisionId and preserve it as parentRevisionId for the entire operation. Initial imports use null. Browser review cookies and reading links cannot authorize imports.
Send Authorization: Bearer OWNER_TOKEN, Content-Type: application/json, and Idempotency-Key: A-NEW-RANDOM-UUID. Save that key alongside the issue's editing state before sending the request:
{
"url": "https://files.oaiusercontent.com/your-file?temporary-download-parameters",
"parentRevisionId": null
}
The URL must be a directly downloadable HTTPS file on an exact host in allowedHosts, with no login, URL credentials, fragment, or custom port. OpenAI's files.oaiusercontent.com and the site's public hostname are enabled by default; additional storage hosts require operator configuration. Redirects are checked at every step, with at most three redirects. The service never forwards your owner bearer or cookies to the file host. It does not retain the download URL. Treat signed URLs as private temporary credentials; do not publish them in the magazine or logs.
Downloads have a 25-second deadline and a 32 MiB compressed limit. ZIPs must contain magazine.json and the HTML/CSS/local assets at the root or inside one common folder. Normal stored/DEFLATE ZIPs are supported, including streaming ZIPs. ZIP64, split/encrypted archives, symlinks, path traversal, duplicate paths, and unsafe expansion are rejected. Existing file limits apply, and the total uncompressed ZIP (including the manifest and metadata) must fit 32 MiB. A PDF alone is not accepted. Server package validation returns the same actionable PACKAGE_INVALID diagnostics as ordinary uploads.
First success returns 202 {issueId,revisionId,state,replayed:false,statusUrl,reviewLinksUrl} after the source has been stored and review queued. Poll statusUrl with the owner bearer to inspect progress and findings. POST to reviewLinksUrl with that bearer to get the user's private reviewUrl; deliver it without redeeming it. An import response means review was queued, not that the magazine passed review or is ready to print.
Retries are scoped to the issue and require its owner bearer:
- Preserve the original key and parent after a lost response, download failure, or timeout. A committed import returns 200 with the same revision and
replayed:true, even if the download URL has expired or later revisions exist. It never re-downloads or creates another revision. The reportedstateis that imported revision's current state. 409 IMPORT_IN_PROGRESSmeans an attempt is running; respectRetry-After(five seconds) and retry the same operation. An interrupted attempt becomes reclaimable after two minutes.IMPORT_LEASE_EXPIREDalso permits retrying the same operation.IMPORT_DOWNLOAD_FAILEDorIMPORT_DOWNLOAD_TIMEOUTpermits obtaining a fresh URL and retrying with the same key and parent. URL changes are allowed because temporary links expire. Until an import succeeds, corrected packages may also use that key. Once it succeeds, a new file requires a new key and the current parent.409 REVISION_CONFLICTmeans a newer upload won. Fetch owner status and decide whether your changes still belong on top of it; use a new key and current parent only when intentionally creating another revision. Never silently replace newer work.IMPORT_KEY_REUSEDmeans the key was paired with a different parent; recover using the original request or choose a new key for a deliberate new revision.IMPORT_URL_DENIEDmeans the URL host or shape is unsupported. Use an approved host or the ordinary manifest/PUT upload. Do not try alternate encodings to bypass this boundary.IMPORT_TOO_LARGE/IMPORT_ZIP_INVALIDrequire fixing the file. Imports allow 40 requests per IP per hour, including retries; back off on 429.
For a configured ChatGPT GPT Action, its openaiFileIdRefs runtime objects contain download_link; a tool adapter can pass that value as url. ChatGPT plugin file inputs use download_url. Obtain the link from the actual file tool; do not invent it from a file ID or use a conversation's sandbox: download link. OpenAI documents GPT Action links as valid for five minutes, so submit promptly. The generic endpoint does not itself install an Action/plugin or make POST available in an ordinary web-reading chat. See OpenAI's file-transfer documentation.
Review, release, and print approval
Build states: awaiting_upload, queued, reviewing, ready, needs_review, needs_changes, failed. Build ready means a prepared reading edition. printReadiness is the current print decision: {status,label,message,errors,warnings,acceptedWarnings,canApprove}. warnings counts unresolved warnings. Status is blocked (red: errors or incomplete/failed review), attention (yellow: warnings need correction or acceptance), ready (green: eligible for exact-proof approval), or reviewing. report.printReady remains the technical-check result; it does not account for warning acceptance or proof approval. purchase.available additionally checks proof approval and provider configuration.
Reports include deterministic and AI diagnostics, page coverage, page count, renderer, and duration. Errors prevent print readiness. Missing/incomplete AI review prevents release. Review is strictly read-only: every uploaded file must match its sealed hash. The legacy changes field is empty for new reviews; older reports may retain historical changes. The user and their agent make corrections and upload a new revision.
GET /v1/issues/{id}/editions/{editionId}/identity, owner bearer or browser review access, returns {editionId,pdfHash,approvedAt}.
Each owner diagnostic has an edition-scoped id such as finding-1, plus severity, source, message, and optional page, path, element, and suggestion. Accepted warnings also have acceptedAt and acceptedBy (user or agent, the declaring client rather than a separately authenticated identity). Reader metadata exposes aggregate readiness and deterministic findings but omits private AI findings; use the owner endpoint for the full report.
POST /v1/issues/{id}/editions/{editionId}/accept-warnings, owner bearer or browser review access:
{
"pdfHash": "64-lowercase-hex-characters",
"diagnosticIds": ["finding-1", "finding-3"],
"acceptedBy": "agent"
}
Fetch the hash from /identity and warning IDs from the latest owner report. Acceptance is additive and idempotent; retries preserve the first acceptance timestamp. Returns the refreshed owner view. Invalid/error IDs reject the entire request with 422 WARNING_REQUIRED; wrong hashes or superseded editions return 409. Acceptance leaves the report immutable, does not waive errors or incomplete review, does not approve the proof, and never transfers to another edition. Agents may accept when the user chooses that outcome or delegates judgment. “Fix the issues” alone does not authorize waiving them.
POST /v1/issues/{id}/editions/{editionId}/approve, owner bearer or browser review access, {pdfHash}. Only for the current edition with printReadiness.canApprove:true, after the user's proof approval. Unresolved warnings return 409 WARNINGS_UNRESOLVED. Records exact-proof approval for printing only. It does not change the reading edition or enable sharing.
POST /v1/issues/{id}/share-link, owner bearer or browser review access: enables sharing and returns {issueUrl} for the currently released edition. Available once a reading edition exists. This creates a read-only alias without invalidating existing reading links.
POST /v1/issues/{id}/sharing, owner bearer or browser review access, {enabled:false} revokes reader access, including previously released content URLs. {enabled:true} restores the same link. Downloads already obtained cannot be revoked. The owner's short-lived preview remains accessible until expiry.
Reading and owner purchasing
GET /v1/read/{readToken}: latest passing reading edition metadata, rendered HTML URL, PDF URL, page-image URLs, purchase availability. The same URL automatically advances after each complete passing review; print approval and warning acceptance are separate. While newer work is processing or blocked, it keeps the previous passing edition with pendingRevision. The page polls and updates in place. Late completion of an older revision cannot move the reader backward. readingRevisionPolicy in capabilities is latest-passing-review. A link holder has no editing authority. Unlisted does not mean authenticated/private; no directory or public search index is provided.
The purchase button stays visible on reading and owner pages, alongside readiness. The buy button opens checkout directly. Operator-issued payment codes authorize a limited order without private review access, as described below. Ordinary card checkout still requires private review access. Seeing the buy button grants no purchasing authority. POST /v1/issues/{id}/checkout, with that issue’s owner bearer token or browser review cookie, accepts {editionId,copies,recipient}. Recipient: {name,email,line1,line2,townOrCity,stateOrCounty,postalOrZipCode,countryCode}. The active delivery countries and 20–50-page retail limit are in GET /v1/capabilities.purchasePolicy; US delivery is enabled initially. shippingMethod and client prices are rejected. The retail price is $20 per copy including shipping. Reading access never grants purchasing authority. Anonymous callers, reader tokens, and another issue’s owner token cannot start checkout. The former POST /v1/read/{readToken}/checkout route returns 403. Never send a client price or asset URL. The service quotes the selected approved edition and redirects to Stripe. Checkout remains disabled until provider keys, matching environments, and qualified print settings are present.
Payment is recognized only by a signed Stripe webhook, not by visiting the success page. The service binds fulfillment to the stored PDF hash and a permanent Prodigi idempotency key. The order lookup link contains a separate capability and displays status without delivery details.
Common errors
- 401: missing or incorrect owner/publishing credential.
- 403: origin restriction, revoked link, or expired signed preview.
- 404: unavailable issue, edition, or file. Do not try to enumerate identifiers.
- 409: stale revision, closed upload, expired review lease, or unapproved edition.
- 413 / 422: resource or package validation failure; inspect diagnostics.
- 429: rate limit; wait rather than creating alternate identities.
- 503: provider or publishing configuration incomplete. Do not claim the upload was printed or paid.
Payment-code checkout
Payment codes are supplied by the site operator and stored hashed. They are scoped to an issue and a printer environment (live or sandbox), with expiry, revocation, quantity/estimated-cost limits, and an atomic use counter. They grant no source, editing, private browser session, or global review authority. Reading access alone still cannot submit an order. purchase.paymentCodeAvailable advertises the option. Customer card checkout may remain disabled while controlled sample-code orders are enabled.
Both endpoints below require the application Origin. Never put a payment code in a URL or published content.
POST /v1/issues/{id}/code-checkout/quote:{paymentCode,editionId,copies,recipient}. The recipient has the same schema as ordinary checkout. Returns{token,expiresAt,environment,editionId,pdfHash,revisionNumber,proofUrl,warnings,price,copies}. The quote expires after 15 minutes. It checks the newest revision, complete passing review, provider configuration, code scope and limits, but does not consume the code or create an order. Unresolved warnings are returned for explicit acceptance.pricecontains only retail terms:{unitAmountCents:2000,amountCents,discountCents,dueCents:0,currency:"USD",shippingIncluded:true}. A code covers the retail total. The provider quote, including any quoted tax, stays internal. Page, destination, and cost limits apply even with a code, and unrelated provider issues still block.POST /v1/code-checkout/{token}/submit:{pdfHash,approveProof:true,confirmOrder:true,acceptedWarningIds:[...]}. Confirms the quoted PDF and all returned warning IDs for this order. Returns 202{orderUrl}. A new revision, expired quote, changed or consumed code, unaccepted warning, or a fresh quote exceeding the cost ceiling blocks submission. Drafts from before the $20 pricing policy returnCHECKOUT_UPDATEDwithout consuming the code; get a new quote. Finalization atomically consumes the code and creates oneauthorizedorder, never a fake Stripe payment. Repeating the same quote token returns that same order even after code consumption or quote expiry. Competing quotes cannot exceed the use limit.
GET /v1/orders/{token} returns {reference,status,copies,createdAt,paymentMethod,paymentCollected,environment,price,requiresAttention,dispatchEstimate,shipments}. reference is the stable MyMagazine MM-… customer reference. status is processing, received, printing, shipped, partially_shipped, cancelled, or needs_attention. No provider reference, internal progress fields, recipient details, or wholesale costs are returned. price is null for historical orders without a retail snapshot. A dispatchEstimate contains a 4–6 business-day range with basis:"usual_production_time"; the public Prodigi API does not expose an order-specific estimated dispatch field. Shipments expose the actual dispatchedAt and an HTTPS trackingUrl when available. Do not interpret “shipped” as “delivered.”
Code authorization never reports payment received. The printer environment and approved PDF are frozen in the order; later uploads or configuration changes cannot redirect a retry. Production retries preserve the provider idempotency key and stop for operator attention after the attempt limit. Fresh retail orders are checked against the current internal fulfillment budget before each provider submission; a budget hold never creates a replacement order.