{"openapi":"3.1.0","info":{"title":"PromptFax GPT Actions","version":"1.0.0","description":"Custom GPT Actions for PromptFax one-off US fax sessions. Uses hosted upload/review, quote, Stripe Checkout, and status polling. Checkout is the human authorization step; PromptFax sends only after Stripe webhook confirmation."},"servers":[{"url":"https://promptfax.app"}],"paths":{"/api/gpt-actions/sessions":{"post":{"operationId":"startPromptFaxSession","tags":["PromptFax GPT Actions"],"summary":"Start or resume a PromptFax GPT Action session","description":"Start or resume a PromptFax session. Store the returned sessionId. Include faxNumber only when the user supplied an actual US number. If the file is only attached in ChatGPT, send the returned PromptFax link and ask for any missing fax number.","security":[{"PromptFaxGptActionKey":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartSessionRequest"}}}},"responses":{"200":{"description":"PromptFax session state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/gpt-actions/sessions/{sessionId}/attach-document-url":{"post":{"operationId":"attachPromptFaxDocumentUrl","tags":["PromptFax GPT Actions"],"summary":"Attach public document links to a PromptFax session","description":"Attach one to five public document links that PromptFax can download. Do not use this for ordinary ChatGPT uploads; send the returned PromptFax upload link instead.","security":[{"PromptFaxGptActionKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"},"description":"PromptFax session identifier returned by startPromptFaxSession."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachDocumentUrlRequest"}}}},"responses":{"200":{"description":"PromptFax session state after attachment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/gpt-actions/sessions/{sessionId}/continue":{"post":{"operationId":"continuePromptFaxSession","tags":["PromptFax GPT Actions"],"summary":"Continue a PromptFax session from the current state","description":"Preferred follow-up after upload, done, ok now what, fax-number changes, or quote acceptance. Reads session state, quotes when document plus fax number are ready, and starts Stripe Checkout only when quoteAccepted is true.","security":[{"PromptFaxGptActionKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"},"description":"PromptFax session identifier returned by startPromptFaxSession."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContinueSessionRequest"}}}},"responses":{"200":{"description":"PromptFax session state after any safe continuation step","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/gpt-actions/sessions/{sessionId}/status":{"get":{"operationId":"getPromptFaxSessionStatus","tags":["PromptFax GPT Actions"],"summary":"Get PromptFax session and delivery status","description":"Read current upload, quote, payment, send, delivery, failure, retry, or cancel state. Use after checkout or progress questions. If uploadStatus is uploaded without pageCount, say PromptFax is still processing and poll again.","security":[{"PromptFaxGptActionKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"},"description":"PromptFax session identifier returned by startPromptFaxSession."}],"responses":{"200":{"description":"PromptFax session state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/gpt-actions/sessions/{sessionId}/retry":{"post":{"operationId":"retryPromptFaxSession","tags":["PromptFax GPT Actions"],"summary":"Prepare a retry for a failed PromptFax session","description":"Prepare a new authorization attempt when the previous failed fax is retry-eligible.","security":[{"PromptFaxGptActionKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"},"description":"PromptFax session identifier returned by startPromptFaxSession."}],"responses":{"200":{"description":"PromptFax retry session state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/gpt-actions/sessions/{sessionId}/cancel":{"post":{"operationId":"cancelPromptFaxSession","tags":["PromptFax GPT Actions"],"summary":"Cancel the active PromptFax session","description":"Cancel the active PromptFax send workflow when cancellation is still possible.","security":[{"PromptFaxGptActionKey":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"},"description":"PromptFax session identifier returned by startPromptFaxSession."}],"responses":{"200":{"description":"PromptFax canceled session state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStatus"}}}},"401":{"description":"Missing or invalid GPT Action key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"PromptFaxGptActionKey":{"type":"apiKey","in":"header","name":"x-promptfax-gpt-action-key"}},"schemas":{"StartSessionRequest":{"type":"object","additionalProperties":false,"properties":{"sessionId":{"type":"string","description":"Optional existing PromptFax session id to resume. If the prior PromptFax uiUrl is in the conversation, parse the session_id query parameter and pass it here."},"faxNumber":{"type":"string","description":"Optional destination US fax number in human or E.164 format. Only include an actual number with digits; if the user says placeholder text such as this US fax number, omit this field and ask for the number."}}},"AttachDocumentUrlRequest":{"type":"object","additionalProperties":false,"required":["fileUrls"],"properties":{"fileUrls":{"type":"array","minItems":1,"maxItems":5,"items":{"type":"string","format":"uri","pattern":"^https://"},"description":"Public PDF/image links that PromptFax can download and attach. For normal ChatGPT uploads, use the PromptFax upload link returned by startPromptFaxSession."}}},"ContinueSessionRequest":{"type":"object","additionalProperties":false,"properties":{"faxNumber":{"type":"string","description":"Destination US fax number to use when the session has a document but no quote yet, or when the user corrects the destination. Only include an actual number with digits; never pass placeholder text."},"quoteAccepted":{"type":"boolean","description":"Set true only after the user explicitly accepts the displayed PromptFax quote or asks to continue to payment. When true and checkout is ready, PromptFax starts hosted Stripe Checkout. Do not set this just because a document was uploaded."}}},"SessionStatus":{"type":"object","additionalProperties":true,"properties":{"sessionId":{"type":["string","null"]},"documentId":{"type":["string","null"],"description":"Non-null when PromptFax has a document associated with the session."},"sendIntentId":{"type":["string","null"]},"faxNumber":{"type":["string","null"]},"status":{"type":"string"},"uploadStatus":{"type":["string","null"],"description":"Document handoff state. attached means the document is ready for quoting. uploaded can be an intermediate upload-session state before the document is attached."},"checkoutStatus":{"type":["string","null"]},"retryEligible":{"type":["boolean","null"]},"pageCount":{"type":["integer","null"],"description":"Number of pages detected in the uploaded/attached document. Non-null means PromptFax can quote once a fax number is available."},"quotedAmountCents":{"type":["integer","null"]},"chargedAmountCents":{"type":["integer","null"]},"uiUrl":{"type":["string","null"],"format":"uri","description":"PromptFax full-app upload/review URL for the required human step."},"nextAction":{"type":["string","null"],"description":"Machine-readable next workflow step, for example attach_document, get_quote, checkout, complete_checkout_then_poll_status, poll_status, retry_failed_fax, start_session, or none."},"requiredHumanStep":{"type":["string","null"],"description":"Human-readable step the user must complete, if any."},"expiresAt":{"type":["string","null"],"format":"date-time"},"messageForLlm":{"type":["string","null"]},"messageForUser":{"type":["string","null"]}}},"ErrorResponse":{"type":"object","additionalProperties":true,"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}