Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Getty Images API

Connect Bolt.new to the Getty Images API by applying for developer access at developer.gettyimages.com, using your API key to search and display watermarked preview images via a Next.js API route, and implementing the licensing flow for purchasing rights to high-resolution images. Getty Images is the premium source for editorial and news photography. All API calls must go through a server-side route — the API key is a credential that should never be exposed in the browser.

What you'll learn

  • How to apply for Getty Images API access and obtain an API key from the developer portal
  • How to search Getty Images and display watermarked previews in a Bolt.new image gallery component
  • How to build a server-side API route that proxies Getty API calls and handles pagination and filtering
  • How to implement the Getty Images licensing flow for downloading purchased high-resolution images
  • How to handle Getty Images' editorial vs creative content distinction in your search and display logic
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read25 minutesSocialApril 2026RapidDev Engineering Team
TL;DR

Connect Bolt.new to the Getty Images API by applying for developer access at developer.gettyimages.com, using your API key to search and display watermarked preview images via a Next.js API route, and implementing the licensing flow for purchasing rights to high-resolution images. Getty Images is the premium source for editorial and news photography. All API calls must go through a server-side route — the API key is a credential that should never be exposed in the browser.

Build a Getty Images Search and Licensing App with Bolt.new

Getty Images is the world's largest premium stock photography agency, with an archive of over 500 million assets including editorial news photography, creative stock images, sports and entertainment photography, and archival historical images. The Getty Images API gives developers programmatic access to search this collection, display watermarked previews, and license images for specific uses. For media companies, news apps, editorial tools, and content platforms built in Bolt.new, the Getty API provides access to the most comprehensive library of editorial photography available.

Getting started with the Getty Images API requires creating a developer account at developer.gettyimages.com and submitting an API application. Unlike many APIs that offer instant access, Getty reviews applications to understand your use case — this typically takes 1-3 business days. Once approved, you receive an API key that authenticates your search and preview requests. The API key approach is straightforward: include it in the Api-Key header on all requests. For licensed downloads (purchasing rights to use images without watermarks), Getty uses OAuth 2.0 — a separate credential layer that requires user authentication. The search and preview tier works with just the API key and is what most developers need for building image galleries, search tools, and content discovery features.

Getty's image collection has an important distinction: editorial content versus creative content. Editorial images document real events — news photography, celebrity events, sports, politics. They can only be used in editorial contexts (news reporting, educational content) and not for commercial advertising. Creative images are cleared for commercial use in advertising, products, and marketing. When building search features, you should filter by this asset_type to show users only the content they are licensed to use for their purpose. Displaying editorial images in a commercial context without the correct license is a legal issue that Getty actively enforces.

Integration method

Bolt Chat + API Route

Getty Images API uses API key authentication for search and preview endpoints — include your API key in the Api-Key header on all requests. Because the API key is a privileged credential (it may be tied to a billing account for licensed downloads), all Getty API calls happen in a Next.js API route in your Bolt.new app. The frontend calls your API route, which proxies to Getty Images and returns search results with watermarked preview URLs. For licensing (purchasing rights), an additional OAuth 2.0 flow is required. Search and preview work in Bolt's WebContainer during development.

Prerequisites

  • A Getty Images developer account at developer.gettyimages.com with an approved API key
  • A Bolt.new project using Next.js (required for server-side API routes that keep the API key out of the browser)
  • Understanding of Getty Images' editorial vs creative content distinction for proper licensing
  • Optional: a Getty Images account with licensing credits for the download/licensing use case
  • Basic understanding of image pagination and lazy loading for large result sets

Step-by-step guide

1

Apply for Getty Images API Access

Navigate to developer.gettyimages.com and click 'Get API Access'. You will need to create a Getty developer account (separate from a regular Getty Images account) and fill out an application form describing your project. Getty wants to understand your use case: what type of application you are building, how you will display images, whether you intend to offer licensing to end users, and your estimated monthly API call volume. Provide specific, honest answers — vague responses slow down approval. Common approved use cases include media company tools, news aggregators, editorial content platforms, creative agency asset browsers, and developer demos/portfolios. After submitting, approval typically takes 1-3 business days. Getty sends your API key by email once approved. The API key looks like a long alphanumeric string and is associated with your developer account. There are two tiers: the Developers tier (free, rate-limited, returns watermarked previews only, no licensing capabilities) and the Partners tier (requires a Getty commercial agreement, enables licensed downloads and higher rate limits). For building and testing, the Developers tier is sufficient. Add the API key to your .env file as GETTY_API_KEY. Getty's API base URL is https://api.gettyimages.com/v3 and all endpoints require the Api-Key header (note: 'Api-Key' with a capital K, not 'Authorization: Bearer'). Test your key by calling the /search/images endpoint — a 200 response confirms the key is working.

Bolt.new Prompt

Set up Getty Images API access in my Next.js Bolt.new app. Create a .env file with GETTY_API_KEY placeholder. Create lib/getty.ts with a gettyRequest(endpoint, queryParams) async helper function that calls https://api.gettyimages.com/v3{endpoint} with the headers: Api-Key set to GETTY_API_KEY and Accept-Language set to 'en-US'. Stringify the queryParams as URL search parameters. If the response is not OK, throw an error with the status and response body. Export the helper. Verify connectivity by creating a simple test: call /search/images?phrase=nature&page_size=1 and return the first result.

Paste this in Bolt.new chat

lib/getty.ts
1// lib/getty.ts
2export async function gettyRequest<T>(
3 endpoint: string,
4 queryParams: Record<string, string | number | boolean> = {}
5): Promise<T> {
6 const apiKey = process.env.GETTY_API_KEY;
7
8 const params = new URLSearchParams();
9 Object.entries(queryParams).forEach(([key, value]) => {
10 if (value !== undefined && value !== null && value !== '') {
11 params.append(key, String(value));
12 }
13 });
14
15 const url = `https://api.gettyimages.com/v3${endpoint}${params.toString() ? '?' + params.toString() : ''}`;
16
17 const response = await fetch(url, {
18 headers: {
19 'Api-Key': apiKey!,
20 'Accept-Language': 'en-US',
21 'Content-Type': 'application/json',
22 },
23 });
24
25 if (!response.ok) {
26 const errorText = await response.text();
27 throw new Error(`Getty API error ${response.status}: ${errorText}`);
28 }
29
30 return response.json() as Promise<T>;
31}

Pro tip: Getty's API uses 'Api-Key' as the header name — note the capital K. This is unusual compared to most APIs that use 'Authorization: Bearer' or 'X-API-Key'. Using the wrong header format results in a 401 Unauthorized response. Also, the header is literally 'Api-Key', not 'api-key' — though HTTP headers are case-insensitive in transit, matching the documented format is safer.

Expected result: The Getty API connection is verified. The gettyRequest helper is ready to use in API routes throughout the app. A test search returns Getty image data.

2

Build the Image Search API Route and Gallery Component

With your API key configured, build the core search functionality. The Getty Images search endpoint is GET /v3/search/images and accepts numerous filtering parameters. The key ones for most applications: phrase (search keywords), page and page_size (pagination, max 100 per page), asset_type (editorial vs creative — critical for correct licensing), orientations (horizontal, vertical, square), number_of_people (none, one, small_group, large_group), and sort_order (best_match, most_popular, newest, oldest). The response includes a result_count (total matching images) and an images array. Each image object contains the id, title, caption, date_created, artist (photographer), asset_type, display_sizes (array of preview URLs at different sizes), and keywords array. The display_sizes array contains objects with a name (comp, preview, thumb) and uri (the image URL). 'thumb' is the smallest (170px), 'preview' is medium (340px), and 'comp' is the largest watermarked preview suitable for layout comping. All of these URLs include Getty's watermark overlay. Use the 'thumb' URIs for grid thumbnails and 'comp' or 'preview' for enlarged image views. During development in Bolt's WebContainer, outbound API calls to Getty Images work correctly from Next.js API routes. You can build and test the full search and gallery interface in the Bolt preview.

Bolt.new Prompt

Create a Next.js API route at app/api/images/search/route.ts that accepts GET with query params: q, page (default 1), pageSize (default 20), assetType (editorial/creative, default creative), orientation. Call the Getty Images search API using the gettyRequest helper. Return formatted results: { images: [{ id, title, caption, artist, assetType, thumbUrl, previewUrl, compUrl }], totalCount, page, pageSize }. Then build a SearchPage component at app/search/page.tsx with a search input, asset type toggle (editorial/creative), orientation filter, masonry image grid showing comp images with photographer credit overlay, and pagination controls.

Paste this in Bolt.new chat

app/api/images/search/route.ts
1// app/api/images/search/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { gettyRequest } from '@/lib/getty';
4
5interface GettyImage {
6 id: string;
7 title: string;
8 caption: string;
9 artist: string;
10 asset_type: string;
11 date_created: string;
12 display_sizes: Array<{ name: string; uri: string }>;
13 keywords: Array<{ text: string }>;
14}
15
16interface GettySearchResponse {
17 result_count: number;
18 images: GettyImage[];
19}
20
21export async function GET(request: NextRequest) {
22 const { searchParams } = new URL(request.url);
23 const q = searchParams.get('q') || '';
24 const page = parseInt(searchParams.get('page') || '1');
25 const pageSize = Math.min(parseInt(searchParams.get('pageSize') || '20'), 100);
26 const assetType = searchParams.get('assetType') || 'creative';
27 const orientation = searchParams.get('orientation') || '';
28
29 if (!q) {
30 return NextResponse.json({ images: [], totalCount: 0 });
31 }
32
33 const data = await gettyRequest<GettySearchResponse>('/search/images', {
34 phrase: q,
35 page,
36 page_size: pageSize,
37 asset_type: assetType,
38 ...(orientation && { orientations: orientation }),
39 fields: 'id,title,caption,artist,asset_type,date_created,display_sizes,keywords',
40 sort_order: 'best_match',
41 });
42
43 const getDisplayUrl = (sizes: Array<{ name: string; uri: string }>, name: string) =>
44 sizes.find((s) => s.name === name)?.uri || '';
45
46 const images = (data.images || []).map((img) => ({
47 id: img.id,
48 title: img.title,
49 caption: img.caption,
50 artist: img.artist,
51 assetType: img.asset_type,
52 dateCreated: img.date_created,
53 thumbUrl: getDisplayUrl(img.display_sizes, 'thumb'),
54 previewUrl: getDisplayUrl(img.display_sizes, 'preview'),
55 compUrl: getDisplayUrl(img.display_sizes, 'comp'),
56 keywords: img.keywords?.slice(0, 8).map((k) => k.text) || [],
57 }));
58
59 return NextResponse.json({ images, totalCount: data.result_count, page, pageSize });
60}

Pro tip: Always request specific fields in your Getty API call using the 'fields' parameter. Without it, Getty returns the full image object with all available metadata — this significantly increases response size and slows down your API route. Request only the fields you actually display.

Expected result: The search API route returns formatted image results with watermarked preview URLs. The gallery component displays a grid of Getty Images thumbnails with photographer credits.

3

Display Image Details and Implement the Licensing Workflow

When a user clicks a gallery image, show a detail view with the full caption, photographer name, date taken, Getty image ID, and usage rights information. The detail page should clearly show whether the image is editorial (news use only) or creative (commercial use allowed). Include a direct link to the image's licensing page on Getty's website — this is the standard approach for developers on the free API tier. The Getty image detail URL follows the pattern: https://www.gettyimages.com/detail/photo/{image-id}. For developers with a Getty partner agreement and OAuth credentials, the licensing API lets you download licensed images programmatically. This requires OAuth 2.0 authentication where the user logs in with their Getty account, authorizes your app, and you exchange the authorization code for tokens to call the /downloads endpoint. The OAuth flow requires a deployed redirect URI — it cannot work with Bolt's WebContainer preview URL since incoming OAuth callbacks need a stable public HTTPS URL. Build the OAuth flow in Bolt but test it after deployment to Netlify. For the detail page accessible to all visitors, display watermarked comp-size images and link to Getty's own licensing UI. The important thing is to never serve un-watermarked Getty images without proper licensing — Getty actively monitors for unauthorized image use and enforces licensing violations.

Bolt.new Prompt

Build an image detail page at app/images/[id]/page.tsx. Fetch image details from the Getty API (GET /images/{id}) to get full metadata: caption, artist, date_created, keywords, asset_type, and all display sizes. Display the comp-size watermarked image prominently. Show: image title, full caption, photographer name, date taken, asset type badge (editorial/creative with tooltip explaining the difference). Show a 'License this image on Getty Images' button that links to https://www.gettyimages.com/detail/photo/{id}. Include the Getty image ID visibly for reference. Add a similar images section by calling the search API with the first 3 keywords.

Paste this in Bolt.new chat

app/images/[id]/page.tsx
1// app/images/[id]/page.tsx
2import { gettyRequest } from '@/lib/getty';
3import { notFound } from 'next/navigation';
4
5interface GettyImageDetail {
6 id: string;
7 title: string;
8 caption: string;
9 artist: string;
10 date_created: string;
11 asset_type: string;
12 display_sizes: Array<{ name: string; uri: string; is_watermarked: boolean }>;
13 keywords: Array<{ text: string; type: string }>;
14}
15
16type Props = { params: { id: string } };
17
18export async function generateMetadata({ params }: Props) {
19 const image = await gettyRequest<GettyImageDetail>(`/images/${params.id}`)
20 .catch(() => null);
21 if (!image) return { title: 'Image Not Found' };
22 return {
23 title: `${image.title} | Getty Images`,
24 description: image.caption?.slice(0, 155),
25 };
26}
27
28export default async function ImageDetailPage({ params }: Props) {
29 const image = await gettyRequest<GettyImageDetail>(`/images/${params.id}`, {
30 fields: 'id,title,caption,artist,date_created,asset_type,display_sizes,keywords',
31 }).catch(() => null);
32
33 if (!image) notFound();
34
35 const compImage = image.display_sizes?.find((s) => s.name === 'comp');
36 const gettyLicenseUrl = `https://www.gettyimages.com/detail/photo/${image.id}`;
37
38 return (
39 <div className="max-w-4xl mx-auto px-4 py-8">
40 <div className="relative aspect-video bg-gray-100 rounded-lg overflow-hidden mb-6">
41 {compImage && (
42 <img
43 src={compImage.uri}
44 alt={image.caption || image.title}
45 className="w-full h-full object-contain"
46 />
47 )}
48 <span className="absolute top-2 right-2 text-xs bg-black/60 text-white px-2 py-1 rounded">
49 {image.asset_type === 'editorial' ? 'Editorial Use Only' : 'Creative'}
50 </span>
51 </div>
52 <h1 className="text-2xl font-bold mb-2">{image.title}</h1>
53 <p className="text-gray-600 mb-4">{image.caption}</p>
54 <div className="flex gap-4 text-sm text-gray-500 mb-6">
55 <span>Photo by: {image.artist}</span>
56 <span>Date: {new Date(image.date_created).toLocaleDateString()}</span>
57 <span>ID: {image.id}</span>
58 </div>
59 <a
60 href={gettyLicenseUrl}
61 target="_blank"
62 rel="noopener noreferrer"
63 className="inline-flex items-center gap-2 bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700"
64 >
65 License on Getty Images
66 </a>
67 </div>
68 );
69}

Pro tip: Always link to Getty's official licensing page for images rather than providing download functionality on the free API tier. Getty Images actively uses reverse image search and licensing enforcement to identify unauthorized image use. The watermarked preview images include invisible digital watermarks in addition to visible ones — always respect Getty's licensing terms.

Expected result: Clicking any gallery image shows the detail page with the watermarked comp-size image, full caption, photographer info, and a clear link to license the image on Getty's website.

Common use cases

Editorial News Photography Search Tool

Build an internal image search tool for a news or media organization that allows journalists and editors to search Getty's editorial archive, preview watermarked images, and initiate licensing for approved images. Filter by event type, date range, and orientation.

Bolt.new Prompt

Build a Getty Images search interface for editorial photography. Create a Next.js API route at app/api/images/search/route.ts that accepts a GET with query params: q (search term), page, pageSize, asset_type (editorial or creative). Call the Getty Images API search endpoint with the Api-Key header. Return the images array with: id, title, caption, display_sizes (preview URL), and asset_type. Build a search page with a search input, image grid (watermarked previews), and pagination. Each image card shows the preview photo, caption, and photographer credit.

Copy this prompt to try it in Bolt.new

Stock Photo Browser for Creative Teams

Build a creative stock photo browser that filters Getty's creative library by orientation, color, and people count. Team members can search, save favorites to a collection, and share shortlists with each other before initiating licensing through Getty's platform.

Bolt.new Prompt

Build a creative stock photo browser using the Getty Images API. Add filters for: orientation (horizontal/vertical/square), number_of_people (none/one/small_group), and minimum_quality_rank (1-3). Search creative images only (asset_type=creative). Display results in a masonry grid layout. Add a 'Save to Favorites' button that stores the image ID and preview URL in Supabase favorites table (linked to the current user). Build a /favorites page that shows all saved images with their Getty image IDs for licensing reference.

Copy this prompt to try it in Bolt.new

Automated Press Release Image Matching

Build a tool that analyzes press release text and automatically suggests relevant Getty Images to accompany the story. Take a press release as input, extract key people, events, and topics, search Getty Images for matching editorial content, and return a curated selection of appropriate images.

Bolt.new Prompt

Build a press release image matcher. Input: a text area for pasting press release content. On submit, extract the top 3 search terms from the text (company names, people, topics — use simple keyword extraction). For each search term, call the Getty Images search API (via our API route) and return the top 3 results. Display a grid of 9 suggested images (3 per search term, labeled with the keyword that found them) with preview images, captions, and Getty image IDs. Add a 'Copy Image ID' button for each image to use when licensing.

Copy this prompt to try it in Bolt.new

Troubleshooting

Getty API returns 401 Unauthorized for all requests

Cause: The Api-Key header is missing, misspelled (wrong capitalization), or the API key itself has not been approved yet — Getty reviews API applications before granting access.

Solution: Verify the header is exactly 'Api-Key' (capital A and K) in your request. Check that GETTY_API_KEY in your .env file matches the key from developer.gettyimages.com exactly. If your application is still under review, you will not be able to make successful API calls until approval.

typescript
1// Correct Getty header format:
2headers: { 'Api-Key': process.env.GETTY_API_KEY }
3
4// WRONG formats that cause 401:
5headers: { 'api-key': process.env.GETTY_API_KEY }
6headers: { 'Authorization': `Bearer ${process.env.GETTY_API_KEY}` }

Image URLs (thumbUrl, previewUrl, compUrl) return 403 Forbidden when accessed in an img tag

Cause: Getty Images display URLs include a short-lived token in the URL that expires after a period of time, or the URL is being hotlinked from a domain that is not registered with Getty.

Solution: Fetch fresh image URLs from the Getty API for each page load rather than caching URL strings long-term. Do not store Getty preview URLs in your database — store only the Getty image ID and re-fetch the display URLs when needed. Getty's URLs are signed and expire.

typescript
1// Store only the Getty image ID, not the URL:
2await supabase.from('favorites').insert({ getty_image_id: image.id, user_id: userId });
3
4// When displaying: fetch fresh URLs from Getty API using the stored ID
5const freshImage = await gettyRequest(`/images/${savedImageId}`, { fields: 'display_sizes' });

Search returns no results for certain queries even though images exist on Getty's website

Cause: The asset_type filter may be excluding results — editorial images will not appear in creative searches and vice versa. Or the free developer API tier may have restrictions on certain content types.

Solution: Try removing the asset_type filter to search both editorial and creative images simultaneously. If searching for specific events or news photography, use asset_type=editorial. If the Developers tier does not return expected results, some content may only be accessible to Partners with a Getty commercial agreement.

typescript
1// Search across both asset types by omitting the asset_type filter
2const data = await gettyRequest('/search/images', {
3 phrase: q,
4 page,
5 page_size: pageSize,
6 // Remove asset_type to search all content
7 fields: 'id,title,caption,artist,asset_type,display_sizes',
8});

Getty Images API calls work in Bolt's preview but fail with CORS errors if called from the browser

Cause: Getty's API does not allow direct browser-to-API calls (CORS is blocked) — all calls must go through a server-side API route. If you accidentally called Getty's API directly from a React component (using fetch in a useEffect), the browser's CORS policy will block the request.

Solution: Move all Getty API calls to a Next.js API route (app/api/...) and have your React components call your own API route instead. Never call https://api.gettyimages.com directly from client-side code.

typescript
1// WRONG — calling Getty directly from browser (CORS error):
2const data = await fetch('https://api.gettyimages.com/v3/search/images?phrase=nature');
3
4// CORRECT — call your own API route from the browser:
5const data = await fetch('/api/images/search?q=nature');
6// The /api/images/search route calls Getty server-side with the API key

Best practices

  • Never call Getty Images API directly from browser-side code — CORS will block it and the API key would be exposed in network requests; always proxy through a Next.js API route
  • Store only Getty image IDs in your database, not the display URLs — Getty's signed preview URLs expire and storing them long-term leads to broken images
  • Always display the editorial vs creative asset_type badge on images — editorial images can only be used in news/editorial contexts, not for commercial advertising or marketing
  • Link to Getty's own licensing page (gettyimages.com/detail/photo/{id}) rather than trying to implement licensing on the free API tier — Getty's terms require proper licensing flow
  • Request specific fields in the Getty API 'fields' parameter to reduce response payload size — the full image object contains dozens of fields you may not need
  • Handle Getty API rate limits gracefully with retry logic — the free developer tier has strict rate limits and may return 429 Too Many Requests under high traffic
  • During development in Bolt's WebContainer, Getty API calls via your Next.js API route work correctly — Getty's API is accessible over standard HTTP and does not require special network configuration

Alternatives

Frequently asked questions

How do I get access to the Getty Images API?

Go to developer.gettyimages.com and apply for API access. Fill out the application form describing your project and use case — Getty reviews applications before granting API keys, typically within 1-3 business days. Once approved, you receive an API key by email. The free Developers tier provides access to search and watermarked preview endpoints. Licensed downloads require a Getty Partners agreement.

Do Getty Images API calls work in Bolt's WebContainer during development?

Yes, when called from a Next.js API route (server-side). Getty's API is accessible over HTTPS from Bolt's WebContainer. However, Getty's API blocks direct browser-to-API calls due to CORS restrictions — you must proxy all calls through a Next.js API route. Never call Getty's API from client-side React code.

What is the difference between Getty's editorial and creative images?

Editorial images document real events — news photography, celebrity events, sports, politics — and can only be used in editorial contexts (news articles, educational content, editorial commentary). They cannot be used for advertising, product promotion, or commercial purposes. Creative images are cleared for commercial use including advertising and marketing. Always filter by asset_type and display this distinction to users to help them choose appropriately licensed images.

Can I display full-resolution Getty Images on my website?

No — without a license, you can only display Getty's watermarked preview images (comp, preview, and thumb sizes). The watermarks are both visible and invisible (digital steganography). Serving un-watermarked Getty images without proper licensing violates Getty's terms of service, and Getty actively enforces licensing through reverse image search and legal action. Always link users to Getty's licensing page for purchasing rights.

Can I store Getty preview image URLs in my database?

No — Getty's preview URLs are signed and time-limited. Storing them leads to broken image links after the URLs expire. Instead, store only the Getty image ID in your database and re-fetch the display URLs from the Getty API each time you need to display the image. Getty's API response time is fast enough that fetching URLs on demand is practical.

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.