Skip to main content
RapidDev - Software Development Agency
v0-integrationsNext.js API Route

How to Integrate Getty Images API with V0

To integrate the Getty Images API with V0 by Vercel, generate an image search UI with V0, create a Next.js API route that searches and retrieves embed codes from the Getty Images API using your API key, and store credentials in Vercel environment variables. Getty Images API access requires approval — the free tier provides embed-only access, while licensing images for download requires a paid Getty API plan.

What you'll learn

  • How to obtain Getty Images API access and understand the difference between embed-only and full licensing tiers
  • How to create a Next.js API route that searches the Getty Images catalog and returns image metadata
  • How to display Getty Images using their official embed codes (iframes) to comply with licensing terms
  • How to build a searchable image library UI with V0 for finding premium stock photography
  • How to handle Getty Images licensing requirements in your application's UI and terms
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read30 minutesSocialMarch 2026RapidDev Engineering Team
TL;DR

To integrate the Getty Images API with V0 by Vercel, generate an image search UI with V0, create a Next.js API route that searches and retrieves embed codes from the Getty Images API using your API key, and store credentials in Vercel environment variables. Getty Images API access requires approval — the free tier provides embed-only access, while licensing images for download requires a paid Getty API plan.

Premium Stock Photography in Your V0 App with Getty Images API

Getty Images is the gold standard for premium stock photography — the library includes over 477 million images, videos, and music tracks spanning editorial, creative, and archival content. For applications that need high-quality imagery that goes beyond what free platforms like Unsplash or Pixabay offer — sports photography, news events, exclusive celebrity photos, historical archives — the Getty Images API provides programmatic access to this catalog.

The Getty Images API has two distinct tiers with very different capabilities. The free Embed tier lets you display Getty images on your website using Getty's hosted iframe embed codes — the images include a Getty watermark and are intended for editorial use. This requires API access approval but no per-image fees. The full API access tier (requiring a partnership or licensing agreement with Getty) enables image downloads for commercial use, custom creative access, and removal of watermarks. Most developer tutorials and use cases involve the Embed tier.

For V0 developers, the most practical use cases are: building an editorial content platform that embeds Getty photos, creating an internal image search tool for a marketing team, or building a digital asset selection interface for a publication. The search API lets you query by keyword, orientation, image type (photo, illustration, vector), license type, and many other facets — returning rich metadata including editorial descriptions, capture dates, and the embed code for licensed display.

Integration method

Next.js API Route

V0 generates the image search gallery UI. A Next.js API route proxies requests to the Getty Images REST API using your API key — searching the image library, fetching embed codes for display purposes, and (on paid plans) generating download authorizations for licensed images. API credentials stay server-side in Vercel environment variables.

Prerequisites

  • A Getty Images developer account — apply at developers.gettyimages.com; API access requires approval (typically 1-3 business days for the embed tier)
  • Getty Images API key and API secret — obtained after approval from your Getty Images developer portal
  • Understanding of Getty's licensing model: Embed tier allows iframe embeds only (with watermark), full API requires a commercial licensing agreement
  • A V0 account and Next.js project deployed to Vercel — Getty API credentials must be stored as server-side environment variables
  • Familiarity with iframe embedding for the embed tier, as Getty-licensed images are displayed via hosted iframes rather than direct image URLs

Step-by-step guide

1

Generate the Image Search UI with V0

Start with the search interface — this is where V0 shines for image-heavy applications. Prompt V0 to build a search page with a text input, filter controls, and a responsive image grid. The grid should handle varying image aspect ratios gracefully — use a masonry or fixed-aspect-ratio grid depending on your aesthetic preference. For displaying Getty images, you have two options depending on your API tier: the embed tier uses iframes with Getty's hosted embed code (which includes the Getty watermark and copyright), while paid API tiers allow direct image URL display. Design your component to accept both cases — use an iframe container for embed codes and an img tag for direct URLs. Include filter controls that map to Getty's search parameters: orientation (horizontal, vertical, square), image type (photography, illustration, vector), and editorial/creative flag. These filters significantly narrow results to match a user's intent. Also include a loading skeleton state for the search results — Getty API calls typically take 300-800ms, and users need visual feedback that the search is in progress. Prompt V0 to add infinite scroll or pagination to the image grid — Getty's search returns up to 500 results per query and your users will want to browse beyond the first page. A 'Load More' button at the bottom of the grid is simpler to implement than infinite scroll and works well for this use case.

V0 Prompt

Create a stock image search page with a search input bar at the top and filter chips below it for orientation (Any, Horizontal, Vertical) and type (All, Photos, Illustrations). Show search results in a 3-column masonry grid where each image has a fixed-aspect iframe container for Getty embeds. Add a caption below each image showing the image title. Include a loading spinner while fetching and a 'No results found' empty state. Add pagination with Previous/Next buttons at the bottom.

Paste this in V0 chat

Pro tip: Use CSS aspect-ratio: 16/9 on iframe containers to maintain consistent heights across different Getty image aspect ratios — Getty's embed iframes are designed to scale responsively within their container.

Expected result: A responsive image search page in V0 with search input, filter controls, an iframe grid layout, loading states, and pagination — ready to receive real Getty Images embed codes.

2

Create the Getty Images Search API Route

Build the Next.js API route that authenticates with the Getty Images API and searches the image catalog. Getty's API uses OAuth2 client credentials flow — you exchange your API key and secret for an access token, then use that token to make search requests. Access tokens are valid for 30 minutes. The Getty Images REST API v3 base URL is https://api.gettyimages.com/v3. The search endpoint is GET /search/images with parameters for phrase (search keywords), fields (which data to return), page, page_size, orientations, image_type, and many more filters. By default, the API returns a large set of fields — specify only what you need using the fields parameter to improve performance. For embed tier access, the most important field to return is embed_content_url — this is the iframe URL you display to end users. The response also includes id, title, caption, display_sizes (thumbnail URL array), artist, collection_name, and asset_family (editorial vs. creative). Authentication uses HTTP Basic Auth for the token request: base64-encode 'api_key:api_secret' and pass as the Authorization header. The token endpoint is POST https://authentication.gettyimages.com/oauth2/token with grant_type=client_credentials. Cache the resulting token for its expiration period (typically 1800 seconds) to avoid repeated token requests.

app/api/getty/search/route.ts
1import { NextResponse } from 'next/server';
2
3const GETTY_API_KEY = process.env.GETTY_API_KEY!;
4const GETTY_API_SECRET = process.env.GETTY_API_SECRET!;
5const GETTY_BASE = 'https://api.gettyimages.com/v3';
6const GETTY_AUTH_URL = 'https://authentication.gettyimages.com/oauth2/token';
7
8// Simple in-memory token cache (resets on cold start)
9let cachedToken: { value: string; expiresAt: number } | null = null;
10
11async function getAccessToken(): Promise<string> {
12 if (cachedToken && Date.now() < cachedToken.expiresAt - 60000) {
13 return cachedToken.value;
14 }
15
16 const credentials = Buffer.from(`${GETTY_API_KEY}:${GETTY_API_SECRET}`).toString('base64');
17
18 const response = await fetch(GETTY_AUTH_URL, {
19 method: 'POST',
20 headers: {
21 Authorization: `Basic ${credentials}`,
22 'Content-Type': 'application/x-www-form-urlencoded',
23 },
24 body: 'grant_type=client_credentials',
25 });
26
27 if (!response.ok) {
28 throw new Error(`Getty auth failed: ${response.status}`);
29 }
30
31 const data = await response.json();
32 cachedToken = {
33 value: data.access_token,
34 expiresAt: Date.now() + data.expires_in * 1000,
35 };
36 return data.access_token;
37}
38
39export async function GET(request: Request) {
40 const { searchParams } = new URL(request.url);
41 const phrase = searchParams.get('phrase') || '';
42 const page = searchParams.get('page') || '1';
43 const orientation = searchParams.get('orientation') || '';
44
45 if (!phrase) {
46 return NextResponse.json({ error: 'phrase parameter required' }, { status: 400 });
47 }
48
49 try {
50 const token = await getAccessToken();
51
52 const params = new URLSearchParams({
53 phrase,
54 page_size: '30',
55 page,
56 fields: 'id,title,caption,display_sizes,embed_content_url,artist,collection_name,asset_family',
57 ...(orientation && { orientations: orientation }),
58 });
59
60 const response = await fetch(`${GETTY_BASE}/search/images?${params}`, {
61 headers: {
62 Authorization: `Bearer ${token}`,
63 'Api-Key': GETTY_API_KEY,
64 },
65 next: { revalidate: 300 },
66 });
67
68 if (!response.ok) {
69 return NextResponse.json(
70 { error: 'Getty search failed' },
71 { status: response.status }
72 );
73 }
74
75 const data = await response.json();
76
77 const images = data.images.map((img: any) => ({
78 id: img.id,
79 title: img.title,
80 caption: img.caption,
81 thumbnail: img.display_sizes?.find((s: any) => s.name === 'thumb')?.uri || '',
82 embedUrl: img.embed_content_url || '',
83 artist: img.artist,
84 collection: img.collection_name,
85 isEditorial: img.asset_family === 'editorial',
86 }));
87
88 return NextResponse.json({
89 images,
90 totalCount: data.result_count,
91 page: parseInt(page),
92 });
93 } catch (error) {
94 console.error('Getty API error:', error);
95 return NextResponse.json({ error: 'Failed to search Getty Images' }, { status: 500 });
96 }
97}

Pro tip: Getty's search API supports a 'sort_order' parameter — use 'best_match' for relevance ranking or 'newest' to surface recent editorial images. For creative stock searches, 'best_match' produces the best results; for breaking news editorial searches, 'newest' is more appropriate.

Expected result: GET /api/getty/search?phrase=technology+office returns an array of Getty image objects with IDs, titles, thumbnails, and embed URLs.

3

Add Getty Images Credentials to Vercel Environment Variables

Store your Getty Images API key and API secret in Vercel's environment variable system. These credentials authenticate your entire application to the Getty Images API — if exposed, anyone could search the Getty catalog on your behalf and consume your API quota. Go to your Getty Images developer account at developers.gettyimages.com, navigate to your application's API credentials page, and copy your API key and API secret. These are separate from your Getty Images account login credentials — they're generated when you create a developer application. In Vercel Dashboard → Settings → Environment Variables, create two new variables: GETTY_API_KEY (your application's API key) and GETTY_API_SECRET (your application's secret key). Both should be server-only variables — do not add the NEXT_PUBLIC_ prefix, as these credentials must never reach the browser. Select all three scopes (Production, Preview, Development) and click Save. For local development, add both variables to your .env.local file. Getty's sandbox and production environments use the same API key — there is no separate sandbox environment, but the developer tier restricts access to embed-only content automatically based on your API agreement tier. After adding the variables in Vercel, redeploy your application from the Deployments tab.

.env.local
1# .env.local
2GETTY_API_KEY=your_getty_api_key_here
3GETTY_API_SECRET=your_getty_api_secret_here

Pro tip: Getty Images API keys are tied to a specific domain in some agreement tiers. If your API calls return 401 errors in production but work locally, check whether your Getty application is configured with a domain restriction and update it to match your Vercel domain.

Expected result: GETTY_API_KEY and GETTY_API_SECRET are visible in Vercel environment variables, and the search API route returns real image results from the Getty catalog.

4

Display Getty Images with Embed Codes and Licensing Compliance

Getty Images has specific requirements for how images from the Embed API must be displayed. Images accessed via the embed tier must be shown using Getty's official iframe embed code — you cannot display them as plain img tags or download the image files. The iframe includes Getty's watermark and a link back to Getty Images, which is a licensing requirement. In your React component, replace the img tags in your gallery with iframe elements using the embedUrl from the API response. Getty's embed iframes are designed to be responsive — set width to 100% and let the height be determined by the iframe content, or use a fixed aspect ratio container. Update your V0-generated component to render iframes for embed-tier images. Use the embedUrl from your API response as the iframe src. Add a title attribute for accessibility. The Getty iframe handles its own loading state, but you can show a loading skeleton in the container div before the iframe loads by listening to the iframe's onLoad event. For applications that need direct image URLs (for use as CSS backgrounds, canvas drawing, or server-side processing), you must have a full commercial API licensing agreement with Getty. The embed tier is explicitly for web display only via their hosted iframe player. This is important to communicate in your app's terms of service.

V0 Prompt

Update the image gallery to display Getty images using iframes instead of img tags. For each image result, render an iframe with the src set to the image's embedUrl property. Wrap each iframe in a div with aspect-ratio: 16/9 and overflow: hidden. Show the image title and artist name below each iframe. Add an 'Editorial' or 'Creative' badge on each card based on the isEditorial property.

Paste this in V0 chat

components/GettyImageCard.tsx
1// components/GettyImageCard.tsx
2interface GettyImageCardProps {
3 id: string;
4 title: string;
5 caption?: string;
6 embedUrl: string;
7 artist?: string;
8 isEditorial: boolean;
9}
10
11export function GettyImageCard({ title, embedUrl, artist, isEditorial }: GettyImageCardProps) {
12 return (
13 <div className="rounded-lg overflow-hidden border border-gray-200 shadow-sm">
14 <div className="relative" style={{ aspectRatio: '16/9' }}>
15 {embedUrl ? (
16 <iframe
17 src={embedUrl}
18 title={title}
19 width="100%"
20 height="100%"
21 style={{ border: 'none' }}
22 allowFullScreen
23 scrolling="no"
24 referrerPolicy="no-referrer-when-downgrade"
25 />
26 ) : (
27 <div className="w-full h-full bg-gray-100 flex items-center justify-center">
28 <span className="text-gray-400 text-sm">No preview available</span>
29 </div>
30 )}
31 <span
32 className={`absolute top-2 right-2 text-xs px-2 py-0.5 rounded font-medium ${
33 isEditorial
34 ? 'bg-blue-100 text-blue-800'
35 : 'bg-green-100 text-green-800'
36 }`}
37 >
38 {isEditorial ? 'Editorial' : 'Creative'}
39 </span>
40 </div>
41 <div className="p-3">
42 <p className="text-sm font-medium line-clamp-2">{title}</p>
43 {artist && (
44 <p className="text-xs text-gray-500 mt-1">© {artist} / Getty Images</p>
45 )}
46 </div>
47 </div>
48 );
49}

Pro tip: Always display 'Getty Images' attribution and the photographer credit in your UI — this is both a licensing requirement for the embed tier and good practice for respecting photographers' rights. Include it in the caption below each image card.

Expected result: The gallery displays Getty images as embedded iframes with proper attribution, editorial/creative badges, and titles — compliant with Getty's embed tier licensing requirements.

Common use cases

Editorial Image Search for Content Teams

Build an internal image search tool where your editorial or marketing team can search Getty's library, preview images, and get embed codes or download URLs for approved images. The tool saves time compared to navigating Getty's website and can integrate directly with your CMS workflow.

V0 Prompt

Create an image search page with a prominent search input and a masonry grid of results. Each image card shows a thumbnail, caption, collection type (Editorial/Creative), orientation badge, and a 'Copy Embed Code' button. Include filter options for orientation (horizontal/vertical), image type (photo/illustration), and editorial/creative. Fetch results from /api/getty/search.

Copy this prompt to try it in V0

Embeddable Photo Gallery for Editorial Content

Create a photo gallery component for an editorial blog or news site that displays Getty-licensed images using their official embed codes. The gallery fetches images from a specific Getty collection or event via the API and renders them in a responsive grid with captions.

V0 Prompt

Build a photo gallery section that displays images using Getty Images embed iframes. Show images in a 3-column responsive grid. Each image shows in a 16:9 iframe container with the caption below. Add a loading state while embed codes load. Accept an array of Getty embed codes as props.

Copy this prompt to try it in V0

Stock Photo Licensing Workflow

Build a licensing request workflow where users search for images, select ones they want to license, and submit a licensing request that creates a saved collection in Getty for follow-up. Show pricing estimates based on image type and usage rights.

V0 Prompt

Create a stock photo licensing tool with a search input and results grid. Add a 'Save to Collection' button on each image that adds it to a saved list panel on the right. The panel shows saved images with checkboxes and a 'Request Licensing' button that posts the selected image IDs to /api/getty/license-request. Show a confirmation message after submission.

Copy this prompt to try it in V0

Troubleshooting

Getty API returns 401 Unauthorized — 'InvalidApiKey' or 'InvalidAccessToken'

Cause: The API key or secret is incorrect, the access token has expired, or the API key doesn't have permission for the endpoint being called.

Solution: Verify both GETTY_API_KEY and GETTY_API_SECRET are correct in your Vercel environment variables. Check that the token caching logic is not serving an expired token — the token is valid for 1800 seconds but serverless functions can cache in memory across warm invocations. If using the in-memory cache pattern, verify the expiry check logic.

typescript
1// Ensure token expiry check accounts for clock drift
2if (cachedToken && Date.now() < cachedToken.expiresAt - 120000) { // 2-minute buffer
3 return cachedToken.value;
4}

Getty embed iframes show a broken layout or don't render in the app

Cause: The iframe embed URL may be missing required parameters, the container has restrictive CSS overflow settings, or Content Security Policy headers block the Getty iframe source.

Solution: Check your Next.js Content-Security-Policy headers to ensure embed.gettyimages.com and related Getty domains are in the frame-src allowlist. Also verify the embed container has no overflow: hidden on the iframe itself (only on the wrapper div). Check that embedUrl from the API is not null or undefined — use a conditional render.

typescript
1// next.config.ts — Allow Getty embed iframes
2{
3 key: 'Content-Security-Policy',
4 value: "frame-src 'self' https://embed.gettyimages.com https://*.gettyimages.com"
5}

Search returns results but embed URLs are null or missing

Cause: Not all Getty images are available in the embed tier — rights-managed and some editorial images require a full commercial license and don't have public embed URLs.

Solution: Filter your search results to images that have a valid embed_content_url. Add an image_type filter for creative stock images, which have broader embed availability. For editorial content, only some images are available for embedding; others require commercial licensing.

typescript
1// Filter out images without embed URLs
2const images = data.images
3 .filter((img: any) => img.embed_content_url)
4 .map((img: any) => ({ /* ... */ }));

Best practices

  • Always display proper Getty Images attribution including photographer/artist name and the Getty Images logo or text credit — this is required by the embed tier license agreement
  • Filter API results by embed_content_url availability before displaying them — not all Getty images are available for embedding, and showing broken iframes degrades user experience
  • Cache Getty API token and search results aggressively — the access token is valid for 30 minutes and search results for popular queries rarely change within minutes, so caching prevents unnecessary API calls
  • Be transparent with your users about editorial vs. creative licensing — editorial images cannot be used for commercial purposes (advertising, product promotion), while creative images can
  • Implement rate limiting on your /api/getty/search route to prevent a single user from exhausting your Getty API quota — consider adding a per-IP or per-session rate limit
  • Include a clear 'Powered by Getty Images' attribution on pages displaying Getty content — this is typically required by the embed API terms
  • Use the fields parameter in every Getty API request to request only the data your UI needs — the full image metadata object is large, and requesting unnecessary fields wastes bandwidth

Alternatives

Frequently asked questions

Do I need to pay for Getty Images API access?

The Getty Images Embed API tier is free but requires approval at developers.gettyimages.com. It allows you to embed Getty images using their hosted iframes with watermarks. Downloading images for commercial use requires a commercial licensing agreement with Getty, which has separate pricing based on usage volume and image types.

Can I display Getty images as plain img tags or download them with the free API?

No — the embed tier only allows display via Getty's official iframe embed codes, which include their watermark and copyright notice. Using direct image URLs to display images without the watermark, or downloading image files, requires a commercial API license. Using Getty images outside of their permitted embed method violates their terms and can result in copyright claims.

What is the difference between Getty editorial and creative images?

Editorial images document real events (news, sports, entertainment) and can only be used for editorial purposes — news articles, educational content, commentary. They cannot be used for advertising or commercial promotion. Creative images are studio shoots, conceptual photography, and illustrations cleared for commercial use — you can use them in ads, product promotions, and branded content with the appropriate license.

How do I handle the Getty Images attribution requirement in my app?

Getty requires visible attribution on all embedded images. The iframe embed code automatically includes Getty's branding, but you should also display the photographer's name (from the artist field in the API response) and a 'Getty Images' text credit below each image. This is both a legal requirement and good practice for respecting photographers' rights.

How many API calls can I make with the free Getty Images embed tier?

Getty's API documentation specifies rate limits in the developer portal, but they're not prominently published. In practice, the embed tier is designed for web app use and supports reasonable request volumes. Add caching to your Next.js API route (next: { revalidate: 300 }) to reduce redundant API calls, and contact Getty's developer support if you need higher rate limits for a high-traffic application.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.