sunpeak API
ChatGPT Only
Overview
These hooks wrap the ChatGPT window.openai runtime APIs, providing typed React hooks for host-specific features that go beyond the MCP Apps standard. They are available only when running inside ChatGPT (or the inspector with the ChatGPT host selected).
These hooks throw if called outside ChatGPT. Always feature-detect with isChatGPT() before using them.
Import
import { useUploadFile , useRequestModal , useRequestCheckout } from 'sunpeak/host/chatgpt' ;
import { isChatGPT } from 'sunpeak/host' ;
Feature Detection Pattern
import { isChatGPT } from 'sunpeak/host' ;
import { useUploadFile } from 'sunpeak/host/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.
image/png, image/jpeg, image/webp
Usage
import { useUploadFile } from 'sunpeak/host/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 } /> ;
}
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/host/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/host/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/host/chatgpt' ;
import type { OpenAIRuntime } from 'sunpeak/host/chatgpt' ;
const runtime : OpenAIRuntime | undefined = getOpenAIRuntime ();
if ( runtime ?. openExternal ) {
runtime . openExternal ({ href: 'https://example.com' });
}
Inspector Support
When the ChatGPT host is selected in the Inspector , 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
Host Detection Detect which host is running your app.
Inspector Test ChatGPT hooks locally with the mock runtime.