Seedance 2.5 from ByteDance is officially available on Apiframe.

How to Integrate a Unified Media API With React

Learn how to integrate unified media API with React apps using Apiframe, secure server-side requests, async jobs, previews, and error handling.

Renaud Published August 20, 2026 August 20, 2026 · 9 min read
How to Integrate a Unified Media API With React

A React app can add image, video, and music generation through one API. The hard part is keeping your API key private while your interface handles media jobs that take time to finish.

Use Apiframe as your media layer, keep requests on your server, and let React handle form state, job status, and previews. The steps below walk through the full path, from the first prompt to a production-safe result.

Step 1: Choose the API architecture and media workflow

To integrate a unified media API with a React app, start by splitting the work between the browser and your server. React should collect input and show status. Your server should hold the API key and talk to Apiframe. For more background on this kind of setup, see our guide to unified AI APIs.

Use this request path:

  1. A user picks a media type, model, and prompt in React.
  2. React sends that data to your own server route, such as /api/media.
  3. Your server adds the Apiframe API key and sends the request.
  4. Apiframe returns a job ID with a "queued" status.
  5. Your app checks the job status or receives a webhook.
  6. React displays the finished file through a preview component.

Apiframe uses one login method and one job format across its image, video, and music endpoints. As your feature grows, you only need to change the endpoint and the model value, not build a new client-side flow for every model.

For your first build, start with image generation. Images make it easy to test prompts, loading states, failed jobs, and output links before you add video or music. Once that works, add a media selector that maps each choice to its matching server-side endpoint.

An API is a defined way for software systems to exchange requests and responses, but your app still needs its own rules for auth, validation, and job state.

Write down your workflow before you build the form. Decide where prompts get checked, where results get saved, and what the user sees after a failed job.

Key takeaway: Keep React focused on user input and display. Keep provider calls, secrets, and usage checks on your server.

Step 2: Create a secure React and server-side API setup

A secure React integration never sends the Apiframe key to the browser. Put the key in your server's environment settings, then expose a small route that only accepts safe, expected data.

Install the official Node and TypeScript SDK if it fits your stack, or use plain HTTP requests from your server instead. Store the secret in an environment variable, such asAPIFRAME_API_KEY. Add your environment file to.gitignorebefore you make the first commit.

React's build variables are not secret. Anyone can inspect the JavaScript your app sends to the browser, so any key placed in client-side code can be copied. A server proxy keeps the key out of that bundle entirely. This is a standard and recommended pattern for protecting API keys in React apps.

Your server route should only accept the fields your product actually needs. For an image form, that might just be a prompt and a model choice. Reject any unrecognized fields if requests could come from outside your own interface.

text
const response = await fetch(`${APIFRAME_BASE}/v2/images/generate`, { method: 'POST', headers: { 'X-API-Key': process.env.APIFRAME_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: body.model, prompt: body.prompt })
}); const data = await response.json();
return Response.json(data, { status: response.status });

Never send the provider's key back in your response. Log a request ID or job ID instead. You should also set a limit on request size, check prompt length, and restrict model names to the values your account actually supports.

In development, allow requests from your React app's origin. In production, set a clear cross-origin policy (this controls which websites are allowed to call your server) and require user login before letting anyone spend shared credits.

Secure React server proxy for unified media API integration

By the end of this step, you should have a React project, a server route, and an API key that never touches the browser. Test the route with one fixed prompt before wiring up real user input.

Step 3: Build the generation form and submit media requests

The form is the user-facing part of your integration. Keep it small at first. A prompt field, a model dropdown, and a submit button are enough to prove the flow works.

Use controlled inputs so React manages the form state directly. Trim extra whitespace from the prompt before submitting. Disable the button while the request is sending, but don't treat that quick response as the full generation time. The initial request only starts a background job.

text
async function submitGeneration(event: React.FormEvent) { event.preventDefault(); setError(null); setStatus('submitting'); const response = await fetch('/api/media', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: prompt.trim(), model }) }); const data = await response.json(); if (!response.ok) { setStatus('idle'); setError(data.error || 'The request could not be started.'); return; } setJobId(data.jobId); setStatus(data.status || 'QUEUED');
}

On the server, map the selected media type to a known, fixed endpoint. Don't let a value from the browser decide where your server sends its request. An open forwarding setup like that can be abused.

Apiframe's image endpoint isPOST /v2/images/generate. Video usesPOST /v2/videos/generate, while music usesPOST /v2/music/generate. The request body follows the same basic pattern each time: provide a model and a prompt, then add model-specific settings only when needed. Our AI video API guide and AI music API guide cover the extra fields each media type typically needs.

For example, your video form might accept a starting image URL and an aspect ratio. Your music form might switch between a short description and full lyrics. Keep those extra fields inside a media-specific object, so your main server contract stays simple to test.

Apiframe supports more than 70 models through the same account and credit balance. Let users pick from a short, curated list instead of exposing every model on day one. The Apiframe model catalog can help you match each model to the right input fields.

Return the job ID to React as soon as the request is accepted. Don't wait for the final file inside that same request. Doing so would tie up a server connection while the model is still rendering.

Pro tip: Save the selected model alongside the job record. If you change your default model later, old jobs will still show which model actually created each asset.

The milestone for this step is simple: submitting the form should produce a visible job ID and a clear "queued" status.

Step 4: Track jobs and render generated media in React

React needs a small set of clear states for handling async media. A job can be queued, processing, completed, or failed. Show each state on purpose, rather than displaying one vague loading spinner the whole time.

After your server returnsjobId, start polling your own status route. That route can callGET /v2/jobs/{id}with the private key. Poll images every few seconds. Video and music often need longer intervals, so don't assume every job finishes at the same speed.

text
useEffect(() => { if (!jobId) return; const timer = window.setInterval(async () => { const response = await fetch(`/api/jobs/${jobId}`); const job = await response.json(); setStatus(job.status); if (job.status === 'COMPLETED') { setResult(job.result); window.clearInterval(timer); } if (job.status === 'FAILED') { setError(job.error || 'Generation failed.'); window.clearInterval(timer); } }, 3000); return () => window.clearInterval(timer);
}, [jobId]);

Clear your polling interval when the component unmounts or the job reaches a final state. Otherwise, a user who navigates away might leave a timer running in the background. Your server should also stop checking after a set maximum job age.

Render the result based on its media type. Use an image element for image output, a video element with controls for video, and an audio element with controls for music. Show a plain text link to the file as a fallback if a preview fails to load.

Files generated by Apiframe stay available on its CDN for 3 months. If your product needs longer access, download the result from the returned URL and save it in storage you control. Store the job ID next to your own asset ID, so support staff can trace a complaint back to its source later.

For user-facing products, webhooks are usually cleaner than repeated polling. Your server receives the completed or failed event, updates the job record, and React reads that record through your normal app API.

Don't trust a message from the client claiming a job is complete. Always fetch the job result on the server, or verify the webhook, before marking an asset ready for download.

React async job tracking and generated media preview interface

By now, a user should be able to submit one prompt, watch its status change, and view the returned media without exposing your API key.

Step 5: Add validation, errors, retries, and production safeguards

A demo can stop at a working preview. A real product needs rules around every request. Add these safeguards before opening generation up to real users at scale.

Validate before spending credits

Check the prompt on both sides of the request. Client-side checks improve the form experience, but server-side checks are what actually protect your account. Set a maximum length that fits the model. Confirm that image URLs come from approved hosts if your workflow accepts reference images.

Keep a record of the user, media type, model, a hash of the prompt, job ID, status, and timestamps. A prompt hash lets you spot duplicate requests without storing more of the user's original text than you need to.

Handle failures with clear rules

Separate user errors from temporary provider errors. A bad prompt or an unsupported setting needs a clear, useful message. A timeout or a provider-side error might be worth retrying automatically.

  • Retry transient HTTP failures with exponential backoff.
  • Stop after a small retry count.
  • Never retry a content rejection without changing the request.
  • Use an idempotency key or stored request record to prevent double submissions.

Return a stable error shape to React, such as{ error, code, retryable }. The UI can then show a retry button only when a retry makes sense.

Protect cost and capacity

Set per-user limits on active jobs. Add a daily credit budget for free users. Your account has a concurrent job limit based on your Apiframe plan, so a sudden burst of activity should go into your own queue rather than fail with repeated errors.

Show the selected model before submission. Model costs vary, and users should understand that a high-resolution video request may use more credits than a quick image test. Credits are refunded automatically when a job fails, but your own records should still capture the reason for the failure.

Use a webhook in production, and make sure your handler can safely process the same event more than once. The same event may reach your server twice, so only update a job to "completed" if its stored state isn't already final.

Finally, test the unglamorous cases. Refresh the page mid-generation. Submit an empty prompt. Close the tab early. Send the same request twice. Remove the source image partway through. Your app is ready when every one of these cases ends in a clear, known state instead of a stuck spinner.

If you'd rather connect generation to an existing workflow than build every screen yourself, Apiframe also supports automation through tools like Make, which can handle triggers from outside your React app entirely.

The general rule of thumb: use polling for a small prototype, then move completion handling to webhooks and durable storage before your traffic grows.

FAQ

Can I call a unified media API directly from React?

You can call your own server route directly from React, but you should never call Apiframe directly using a secret key from the browser. Browser code is visible to anyone using your app, so a key placed there can be copied. Send the prompt to your backend instead. The backend adds the X-API-Key header and returns only the job data React actually needs.

How does React know when media generation is finished?

React can learn that a job is finished through polling or a webhook-backed status route. Polling checks the job ID at set intervals. A webhook sends the result to your server, which updates the status. React then reads that status just like any other piece of app data.

What does Apiframe return after a generation request?

Apiframe returns a job ID and a "queued" status as soon as it accepts a request. The media itself is generated in the background. Your server can poll the job endpoint or wait for a webhook. Once the job completes, the result includes a link, or links, to the generated media.

Can I switch AI models without changing my React UI?

You can switch models without rewriting your main React flow, as long as the input fields stay compatible. Store the model choice as data, validate it on the server, and pass it to the matching Apiframe endpoint. Some models need extra settings, so only show those fields when the selected model actually supports them.

Should I store generated media myself?

Yes, for anything important. Apiframe hosts generated files for 3 months, which is fine for testing and short-lived previews. A production app should copy approved files into its own storage once they're ready. Keep the original job ID on file for support and audit purposes.

Conclusion

Build your first version with a server proxy, one image form, and simple polling. Apiframe uses the same basic job flow across image, video, and music, so you can add more media types later without rebuilding your React state logic. Start with the Apiframe getting started guide, send one test job, and add webhooks before you launch to real users.

The Apiframe dispatch

New models, engineering write-ups, and build guides in your inbox. No noise, unsubscribe anytime.