---
title: "Ultimate Giphy to Tenor API Migration Guide"
description: "Giphy has started charging for its API - learn how to migrate to the Tenor API to continue using GIFs for free."
canonicalUrl: "https://zuplo.com/learning-center/migrate-giphy-api-to-tenor-api"
pageType: "learning-center"
authors: "adrian"
tags: "APIs, Tutorial"
image: "https://zuplo.com/og?text=Ultimate%20Giphy%20to%20Tenor%20API%20Migration%20Guide"
---
If you haven't heard the news yet - Giphy is going to
[start charging for their API](https://www.reddit.com/r/iOSProgramming/comments/1gb982d/giphy_api_no_longer_free/).
The API won't be cheap either - with the standard plan start at nearly $9K
annually.

![Giphy pricing plan](/media/posts/2024-11-11-migrate-giphy-api-to-tenor-api/image.png)

This is pretty similar to [what Reddit did](/learning-center/reddit-api-guide) a
while back, and is all too common now that data is becoming increasingly useful
for training LLMs (check out our
[data API monetization guide](/learning-center/building-apis-to-monetize-proprietary-data)
for more examples). If you've been using the Giphy API to add GIFs and stickers
to your apps, you might be considering a switch to the
[Tenor API](https://tenor.com/gifapi). Aside from costs, maybe you're looking
for different features, better performance, or just curious about what Tenor has
to offer. Whatever the reason, this guide is here to help you make a smooth
transition from the Giphy API to the Tenor API.

We'll walk through the key differences between the two APIs, how to map
endpoints, adjust parameters, handle responses, and share some tips along the
way. Let's dive in!

## Table of Contents

1. [Why Switch to Tenor API?](#why-switch-to-tenor-api)
2. [Setting Up Your Tenor API Key](#setting-up-your-tenor-api-key)
3. [Comparing Endpoints](#comparing-endpoints)
4. [Adjusting Request Parameters](#adjusting-request-parameters)
5. [Handling Responses and Data Structures](#handling-responses-and-data-structures)
6. [Code Examples](#code-examples)
7. [Best Practices](#best-practices)
8. [Conclusion](#conclusion)

---

## Why Switch to Tenor API?

The new API costs is obviously a huge factor in why you would want to migrate to
Tenor - but here are some other differences between what Tenor offers compared
to Giphy:

- **Different Content**: Tenor might have the specific GIFs or stickers you're
  looking for. Many users have complained that Giphy's catalog has become too
  "vanilla" and "PG".
- **Features**: Tenor offers unique features like emoji search, localized
  content, and more.
- **Performance**: You might experience better performance or response times
  with Tenor. Some of the largest companies in the world like Facebook and
  LinkedIn rely on Tenor's API - which runs on Google's infrastructure.
- **Integration**: Tenor's API might better fit your application's needs.

## Setting Up Your Tenor API Key

First things first, you'll need an API key to use the Tenor API.

1. **Visit Tenor Developers Page**: Go to
   [Tenor's Quickstart guide](https://developers.google.com/tenor/guides/quickstart).
2. **Sign Up**: Create a Google Cloud Console account if you haven't already and
   connect an existing project.
3. **Obtain API Key**: Once logged in and a project is connected, you can obtain
   your API key.

**Note**: Tenor
[strongly recommends](https://developers.google.com/tenor/guides/endpoints#:~:text=Best%20practices-,To%20differentiate%20your%20integrations%2C%20provide%20a%20client_key%20parameter%20along%20with%20the%20API%27s%20key.,-Provide%20the%20user%27s)
providing a `client_key` parameter with your API key in all requests to
differentiate your application.

## Comparing Endpoints

Let's map out the equivalent endpoints between Giphy and Tenor.

### Does Giphy or Tenor offer an OpenAPI/Swagger Specification?

Unfortunately, to my knowledge, there is no official OpenAPI specification for
Tenor or Giphy's APIs. This is pretty frustrating, since it would provide a
side-by-side comparison of endpoints. I decided to create unofficial
specifications which you can find
[in this repo](https://github.com/zuplo-samples/Giphy-OpenAPI/blob/main) for
Giphy's API and
[in this repo](https://github.com/zuplo-samples/Tenor-OpenAPI/tree/main) for
Tenor's API. I used both of these to create the comparison guide below - but
please take a look at both the [Giphy](https://developers.giphy.com/docs/api/)
and [Tenor](https://developers.google.com/tenor/guides/endpoints) API
documentation for the latest changes.

### Trending Content

- **Giphy**: `/v1/gifs/trending`
- **Tenor**: `/featured` (for featured content)

### Search

- **Giphy**: `/v1/gifs/search`
- **Tenor**: `/search`

### Random GIF

- **Giphy**: `/v1/gifs/random`
- **Tenor**: `/random`

### Translate Phrase to GIF

- **Giphy**: `/v1/gifs/translate`
- **Tenor**: Tenor does not have a direct equivalent but you can perform a
  search with a specific query.

### Get GIF by ID

- **Giphy**: `/v1/gifs/{gif_id}`
- **Tenor**: `/posts` (use the `ids` parameter)

### Autocomplete

- **Giphy**: `/v1/gifs/search/tags`
- **Tenor**: `/autocomplete`

### Trending Search Terms

- **Giphy**: `/v1/trending/searches`
- **Tenor**: `/trending_terms`

## Adjusting Request Parameters

The request parameters in Tenor's API have some differences from Giphy's. Here's
how to adjust them:

### API Key

- **Giphy**: `api_key`
- **Tenor**: `key`

### Search Query

- **Giphy**: `q`
- **Tenor**: `q`

### Limit Results

- **Giphy**: `limit` (default 25)
- **Tenor**: `limit` (default 20, max 50)

### Offset/Pagination

- **Giphy**: `offset`
- **Tenor**: `pos` (use the `next` value from the previous response)

### Content Rating

- **Giphy**: `rating` (`g`, `pg`, `pg-13`, `r`)
- **Tenor**: `contentfilter` (`off`, `low`, `medium`, `high`)

### Language

- **Giphy**: `lang` (2-letter ISO 639-1 code)
- **Tenor**: `locale` (`xx_YY` format, e.g., `en_US`)

### Random ID

- **Giphy**: `random_id`
- **Tenor**: Not directly applicable, but you can manage user sessions
  differently.

## Handling Responses and Data Structures

The response objects from Tenor and Giphy APIs have different structures. You'll
need to adjust how you parse the data.

### Giphy Response Structure

```json
{
  "data": [...],
  "pagination": {...},
  "meta": {...}
}
```

### Tenor Response Structure

```json
{
  "results": [...],
  "next": "string"
}
```

### Accessing GIF URLs

- **Giphy**: Access via `images.original.url` in each GIF object.
- **Tenor**: Access via `media_formats` in each result object.

### Example: Extracting GIF URLs

**Giphy Example**:

```typescript
const gifUrl = response.data[0].images.original.url;
```

**Tenor Example**:

```typescript
const gifUrl = response.results[0].media_formats.gif.url;
```

## Code Examples

Let's look at some code snippets to illustrate the changes.

### JavaScript Fetch Example

**Giphy Search Request**:

```typescript
fetch(
  "https://api.giphy.com/v1/gifs/search?api_key=YOUR_GIPHY_API_KEY&q=funny+cat&limit=10",
)
  .then((response) => response.json())
  .then((data) => {
    const gifUrl = data.data[0].images.original.url;
    console.log(gifUrl);
  });
```

**Tenor Search Request**:

```typescript
fetch(
  "https://tenor.googleapis.com/v2/search?key=YOUR_TENOR_API_KEY&q=funny+cat&limit=10",
)
  .then((response) => response.json())
  .then((data) => {
    const gifUrl = data.results[0].media_formats.gif.url;
    console.log(gifUrl);
  });
```

### Python Example

**Giphy Trending GIFs**:

```python
import requests

response = requests.get(
    'https://api.giphy.com/v1/gifs/trending',
    params={'api_key': 'YOUR_GIPHY_API_KEY', 'limit': 10}
)
data = response.json()
gif_url = data['data'][0]['images']['original']['url']
print(gif_url)
```

**Tenor Featured GIFs**:

```python
import requests

response = requests.get(
    'https://tenor.googleapis.com/v2/featured',
    params={'key': 'YOUR_TENOR_API_KEY', 'limit': 10}
)
data = response.json()
gif_url = data['results'][0]['media_formats']['gif']['url']
print(gif_url)
```

## Best Practices

- **Provide `client_key`**: Tenor recommends using a `client_key` to
  differentiate your application.
- **Handle Pagination Properly**: Use the `next` token from Tenor's response for
  pagination.
- **Respect Content Filters**: Adjust `contentfilter` in Tenor to match your
  application's audience.
- **Optimize Media Formats**: Use the `media_filter` parameter in Tenor to
  reduce response size.
- **Localize Content**: Utilize the `locale` parameter to get region-specific
  content.
- **Register Shares**: Consider using Tenor's `/registershare` endpoint when
  users share content to improve search relevancy.

## Conclusion

API migrations are never easy - even just finding all of the references to
Giphy's API in your code can be a challenge. In the age of AI - if you currently
are using a free API that is a broker of user-generated content, you should
expect a force migration to a paid plan sometime soon. Sometimes you can avoid
this headache by building the right abstractions, like a
[simple API integration platform](/learning-center/building-an-api-integration-platform)
using Zuplo.