Overview
These hooks wrap the ChatGPT window.openai runtime APIs, providing typed React hooks for platform features that go beyond the MCP Apps standard. They are available only when running inside ChatGPT (or the simulator with the ChatGPT host selected).
These hooks throw if called outside ChatGPT. Always feature-detect with isChatGPT() before using them.
Import
import { useUploadFile , useGetFileDownloadUrl , useRequestModal , useRequestCheckout } from 'sunpeak/platform/chatgpt' ;
import { isChatGPT } from 'sunpeak/platform' ;
Feature Detection Pattern
import { isChatGPT } from 'sunpeak/platform' ;
import { useUploadFile } from 'sunpeak/platform/chatgpt' ;
function MyResource () {
// Only use ChatGPT hooks when running on ChatGPT
if ( ! isChatGPT ()) {
return < p > File upload requires ChatGPT. </ p > ;
}
return < FileUploader /> ;
}
function FileUploader () {
const uploadFile = useUploadFile ();
// Safe to call — we're inside ChatGPT
// ...
}
useUploadFile
Upload a file from the app UI into the ChatGPT conversation.
Signature
function useUploadFile () : ( file : File ) => Promise < CreateFileResult >
Returns
uploadFile
(file: File) => Promise<CreateFileResult>
Async function that uploads a file and returns its ID.
CreateFileResult
The ID of the uploaded file. Use with useGetFileDownloadUrl to retrieve a download URL.
image/png, image/jpeg, image/webp
Usage
import { useUploadFile } from 'sunpeak/platform/chatgpt' ;
function ImageUploader () {
const uploadFile = useUploadFile ();
const handleChange = async ( e : React . ChangeEvent < HTMLInputElement >) => {
const file = e . currentTarget . files ?.[ 0 ];
if ( ! file ) return ;
const { fileId } = await uploadFile ( file );
console . log ( 'Uploaded:' , fileId );
};
return < input type = "file" accept = "image/*" onChange = { handleChange } /> ;
}
useGetFileDownloadUrl
Get a temporary download URL for a file by its ID.
Signature
function useGetFileDownloadUrl () : ( params : { fileId : string }) => Promise < FileDownloadUrlResult >
Returns
getFileDownloadUrl
(params: { fileId: string }) => Promise<FileDownloadUrlResult>
Async function that retrieves a temporary download URL.
FileDownloadUrlResult
Temporary URL to download the file.
Usage
import { useGetFileDownloadUrl } from 'sunpeak/platform/chatgpt' ;
import { useState , useEffect } from 'react' ;
function FilePreview ({ fileId } : { fileId : string }) {
const getFileDownloadUrl = useGetFileDownloadUrl ();
const [ src , setSrc ] = useState < string >();
useEffect (() => {
getFileDownloadUrl ({ fileId }). then (({ downloadUrl }) => setSrc ( downloadUrl ));
}, [ fileId , getFileDownloadUrl ]);
return src ? < img src = { src } /> : < p > Loading... </ p > ;
}
useRequestModal
Open a host-controlled modal in ChatGPT.
Signature
function useRequestModal () : ( params : OpenModalParams ) => Promise < void >
OpenModalParams
URL of an alternate UI template to load in the modal. Omit to reuse the current UI.
Arbitrary params forwarded to the modal content.
Usage
import { useRequestModal } from 'sunpeak/platform/chatgpt' ;
function SettingsButton () {
const requestModal = useRequestModal ();
return (
< button onClick = { () => requestModal ({ template: 'ui://widget/settings.html' }) } >
Open Settings
</ button >
);
}
useRequestCheckout
Trigger the ChatGPT instant checkout flow.
Signature
function useRequestCheckout () : ( session : CheckoutSession ) => Promise < CheckoutOrder >
CheckoutSession
payment_provider
CheckoutPaymentProvider
required
Payment provider configuration. Show CheckoutPaymentProvider
Payment provider name (e.g. 'stripe').
supported_payment_methods
Accepted payment methods (e.g. ['card', 'apple_pay']).
status
'ready_for_payment'
required
Must be 'ready_for_payment' to initiate checkout.
ISO 4217 currency code (e.g. 'USD').
Line items and totals. Total type (e.g. 'total', 'subtotal').
Amount in smallest currency unit (e.g. cents).
Legal links shown during checkout. type
'terms_of_use' | 'privacy_policy' | string
required
Link type.
Whether to use live or test payment processing.
CheckoutOrder
ID of the checkout session that produced this order.
status
'completed' | string
required
Order status.
Optional permalink to the order receipt.
Usage
import { useRequestCheckout } from 'sunpeak/platform/chatgpt' ;
function BuyButton () {
const requestCheckout = useRequestCheckout ();
const handleBuy = async () => {
try {
const order = await requestCheckout ({
id: 'session-1' ,
payment_provider: {
provider: 'stripe' ,
merchant_id: 'acct_xxx' ,
supported_payment_methods: [ 'card' , 'apple_pay' ],
},
status: 'ready_for_payment' ,
currency: 'USD' ,
totals: [{ type: 'total' , display_text: 'Total' , amount: 999 }],
links: [],
payment_mode: 'live' ,
});
console . log ( 'Order completed:' , order . id );
} catch {
console . log ( 'Checkout cancelled or failed' );
}
};
return < button onClick = { handleBuy } > Buy Now </ button > ;
}
Low-Level Access
For advanced use cases, you can access the window.openai runtime directly:
import { getOpenAIRuntime } from 'sunpeak/platform/chatgpt' ;
import type { OpenAIRuntime } from 'sunpeak/platform/chatgpt' ;
const runtime : OpenAIRuntime | undefined = getOpenAIRuntime ();
if ( runtime ?. openExternal ) {
runtime . openExternal ({ href: 'https://example.com' });
}
Simulator Support
When the ChatGPT host is selected in the Simulator , a mock window.openai runtime is automatically injected into the iframe. This makes isChatGPT() return true and all ChatGPT hooks functional with stub implementations that log to the browser console.
When a different host (e.g. Claude) is selected, window.openai is not injected and isChatGPT() returns false.
See Also
Platform Detection Detect which host platform is running your app.
Simulator Test ChatGPT hooks locally with the mock runtime.