GifSnap documentation

Your platform. A few lines. GIFs.

Choose a native picker, a web component, or a typed client. Start with your platform’s quickstart, then explore the shared GIF and sticker API.

Choose your platform

Pickers handle search, browsing, animation and selection. Clients let you build the interface yourself.

Start with React

Install the package, import the stylesheet, and handle a selection. The picker searches GIFs and returns the selected object through onSelect.

Install with npm
npm install @rowix/gifsnap-react
App.tsx
import { GifPicker } from '@rowix/gifsnap-react';
import '@rowix/gifsnap-react/styles.css';

export default function App() {
  return (
    <GifPicker
      onSelect={(gif) => console.log(gif.url)}
      theme="system"
    />
  );
}

Keep your own interface

Install the JavaScript client from npm and call the API from your existing interface.

The standalone @rowix/gifsnap-js package works without React in Vue, Svelte, browser JavaScript and Node.js. Call search with a query, or trending to browse. Both accept page, limit, and an optional AbortSignal.

Install the JavaScript client
npm install @rowix/gifsnap-js
JavaScript / TypeScript
import { createGifSnapClient } from '@rowix/gifsnap-js';

const gifsnap = createGifSnapClient();
const { data, pagination } = await gifsnap.search({
  query: 'hello', limit: 12,
});

console.log(data[0]?.url);

JavaScript, Vue and Svelte guide ↗

Or use HTTP directly

The public base URL is https://gifsnap.com/api/v1. These endpoints currently accept requests without an API key. Browser requests are supported by the API’s CORS headers.

cURL
curl --get 'https://gifsnap.com/api/v1/gifs/search' \
  --data-urlencode 'q=hello' \
  --data 'page=1' \
  --data 'limit=12'
Vanilla JavaScript example
fetch()
const url = new URL('https://gifsnap.com/api/v1/gifs/search');
url.searchParams.set('q', 'hello');
url.searchParams.set('page', '1');
url.searchParams.set('limit', '12');

const response = await fetch(url);
if (!response.ok) {
  throw new Error('GIF search failed: ' + response.status);
}
const result = await response.json();
const gifs = result.data;
const nextPage = result.pagination.next_page;

Endpoint reference

All paths below are relative to the base URL. Expand an endpoint for its parameters and a request example.

GET/gifs/search

Search GIFs

  • q: required search text.
  • page: page number, starting at 1.
  • limit: requested number of results per page (1–50; default 25). Keep it consistent while paging.

Returns data[] and pagination, plus the search query.

Search GIFs
curl 'https://gifsnap.com/api/v1/gifs/search?q=hello&page=1&limit=12'
GET/gifs/trending

Browse trending GIFs

  • page: page number, starting at 1.
  • limit: requested number of results per page (1–50; default 25). Keep it consistent while paging.

Returns data[] and pagination.

Browse trending GIFs
curl 'https://gifsnap.com/api/v1/gifs/trending?page=1&limit=12'
GET/stickers/search

Search stickers

  • q: required search text.
  • page: page number, starting at 1.
  • limit: requested number of results per page (1–50; default 25). Keep it consistent while paging.

Returns data[] and pagination, plus the search query.

Search stickers
curl 'https://gifsnap.com/api/v1/stickers/search?q=hello&page=1&limit=12'
GET/stickers/trending

Browse trending stickers

  • page: page number, starting at 1.
  • limit: requested number of results per page (1–50; default 25). Keep it consistent while paging.

Returns data[] and pagination.

Browse trending stickers
curl 'https://gifsnap.com/api/v1/stickers/trending?page=1&limit=12'
GET/gifs/{id}

Look up a GIF

Use the exact id returned by a search or trending response. Encode it as a URL path segment. A successful lookup returns the media object directly, without a data wrapper.

Look up by ID
const response = await fetch(
  'https://gifsnap.com/api/v1/gifs/' + encodeURIComponent(gif.id)
);
if (!response.ok) throw new Error('GIF lookup failed');
const item = await response.json();

OpenAPI specification ↗ · Text documentation index ↗ · AI integration guide ↗

Use the returned media object

List responses contain a data array. Use media URLs as returned: they can point to external storage or a CDN, and may use formats such as WebP rather than a .gif extension.

FieldUse it for
idIdentifying the item within GifSnap.
titleA description or alt text; provide a fallback when empty.
urlThe full media URL; keep this for sending, sharing and full-quality playback.
preview_urlA poster or legacy preview that can be a still image. Do not assume it is animated.
animated_previewOptional verified small animation for a picker grid: url, mime_type, width, height, optional byte_size, and animated: true. Dimensions are at most 480 pixels per side; a supplied byte size is at most 512 KiB.
width, heightReserving space for the media.
type, sourceThe media category and source metadata, when supplied.
content_idOptional verified identity for alternate encodings of the same GIF. Use it to avoid repeated clips; keep the original id for lookups.

Use animated_preview.url only when your renderer supports its mime_type. An image element can display GIF or animated WebP; video formats require a video player. If this optional field is missing or loading fails, fall back to url. Keep the full url on the selected object. A static preview_url is a loading placeholder or final error fallback.

Load the next page

Read pagination.has_next and request pagination.next_page when available. Keep the query and limit unchanged. Treat total as response metadata rather than a promise that every result will remain available.

Example pagination object
{
  "page": 1,
  "limit": 12,
  "total": 120,
  "has_next": true,
  "next_page": 2,
  "offset": 0
}

Handle errors thoughtfully

Check the HTTP status before reading a successful response. Search requires q; missing search text returns 400. An unavailable item can return 404. Service or upstream failures can return 503. Show a useful empty state separately from a failed request.

The JavaScript client exposes GifSnapError with code (http, network, timeout, or invalid_response), an optional HTTP status, and retryAfterSeconds when available. Cancellation preserves the signal’s reason, normally AbortError. Requests time out after 15 seconds by default; configure timeoutMs when creating a client to change this.

The public API is currently a best-effort service, without a published SLA. Handle network failures, avoid retry loops, and preserve source metadata with selected media. The package’s code license does not grant rights to every returned media item.

Moving an existing Tenor integration? Follow the migration guide.