• Home
  • FAQ
  • Features
  • Docs
  • About
  • Pricing
Log In
Log InJoin Now

Shelter Software API: Build Custom Pet Listings and Integrations

04/10/2026

Build custom websites, sync shelter data, and automate rescue workflows with PawPlacer's TypeScript SDK and REST API.

We get asked this a lot: "Can I pull our pet data into our own website?" Or "Can we automatically create adopter records from our external form?" Or "We want to build a custom adoption page that matches our brand."

The answer used to be "sort of, with the embed widgets." Now it's just yes.

We published pawplacer-sdk — a TypeScript/JavaScript client for the PawPlacer API. It's on npm, it's typed end to end, and it lets you read and write your shelter data from your own code. Server-side only, so your API key stays safe.

What you can do with it

Build a custom pet listing on your website. Pull your available animals with filters (species, status, search) and display them however you want. Full control over the design. Update automatically when you change something in PawPlacer.

Create records from external forms. If you use a third-party form tool or your own website form, you can create adopter, foster, or pet records in PawPlacer automatically when someone submits.

Sync with other systems. Use updated_since to pull only records that changed since your last sync. Build nightly jobs that keep PawPlacer in sync with whatever else your organization uses.

Display adoption fees dynamically. Pull your fee configuration (species rules, attribute adjustments) and show accurate fees on your website without hardcoding them.

Show contracts. Pull your adopter, foster, volunteer, or surrender contracts as markdown and render them on your site.

Getting started

Install it:

npm install pawplacer-sdk

Generate an API key in Settings > API. There are two types: read keys for websites and dashboards, write keys for backend jobs that create records. Use the right one for what you're doing.

Then set up a client:

import { PawPlacerClient } from "pawplacer-sdk";

const pawplacer = new PawPlacerClient({
  apiKey: process.env.PAWPLACER_API_KEY!,
});

That's it. Now you can do things like:

// Get available dogs
const dogs = await pawplacer.pets.list({
  status: "available",
  species: "dog",
  limit: 12,
});

// Get a specific pet
const pet = await pawplacer.pets.get("pet-uuid");

// List active adopters
const adopters = await pawplacer.people.list({
  type: "adopter",
  status: "active",
});

// Create an adopter from your own form
const newAdopter = await pawplacer.people.create({
  type: "adopter",
  name: "Jane Smith",
  email: "jane@example.com",
  status: "pending",
});

Every response is fully typed. Your editor knows what Pet, Person, AdoptionFeeEntry look like. No guessing.

Custom fields work too

If you've set up custom form fields in PawPlacer (yard size, vet references, whatever), the SDK can read those definitions and include custom field data when creating records:

// See what custom fields exist
const fields = await pawplacer.pets.getCustomFields();

// Create a pet with custom field data
const pet = await pawplacer.pets.create({
  name: "Max",
  species: "dog",
  age_category: "young",
  sex: "male",
  size: "medium",
  status: "available",
  health: "good",
  custom_field_data: {
    microchip_brand: "HomeAgain",
    rescue_origin: "owner_surrender",
  },
});

Built-in caching

GET responses are cached in memory with stale-while-revalidate, so if you're building a website that shows the same pet listing to every visitor, you're not hammering the API on every page load. The default refresh is every 3 hours, but you can tune it:

const pawplacer = new PawPlacerClient({
  apiKey: process.env.PAWPLACER_API_KEY!,
  cache: { enabled: true, refreshFrequency: 60 },
});

You can also clear the cache manually, invalidate specific patterns, or check hit/miss stats. The API's Cache-Control headers take precedence when present.

Idempotency for create operations

Every create call sends an idempotency key automatically, so if a request gets retried (network hiccup, timeout), you don't end up with duplicate records. For background jobs that might replay across restarts, you can pass your own stable key:

const pet = await pawplacer.pets.create(
  { name: "Max", species: "dog", /* ... */ },
  { idempotencyKey: `nightly-sync:${externalId}` },
);

If the key was already used with the same payload, you get the original response back. pawplacer.lastResponseMeta.idempotencyReplay tells you if that happened.

Rate limits and error handling

Rate limits are per API key and vary by endpoint. The SDK exposes them through pawplacer.lastResponseMeta.rateLimit so you can see how many requests you have left. Listing endpoints get 100 requests/hour, individual gets are 400/hour, and create endpoints are 10/hour.

Errors are typed too. PawPlacerApiError for HTTP errors (with status, code, and message), PawPlacerResponseValidationError if a response doesn't match the expected shape. Both are importable from the package.

Works with Next.js, Express, or whatever

The SDK is server-side only by default — it blocks browser usage to keep your API key safe. Use it in API routes, server actions, getServerSideProps, Express handlers, cron jobs, whatever runs on a server.

// Next.js App Router example
// app/api/pets/route.ts
import { PawPlacerClient } from "pawplacer-sdk";

export async function GET() {
  const client = new PawPlacerClient({
    apiKey: process.env.PAWPLACER_API_KEY!,
  });
  const pets = await client.pets.list({
    status: "available",
    limit: 12,
  });
  return Response.json(pets);
}

CommonJS works too if that's your setup.

Why we built this

Shelter websites are important. They're often the first thing a potential adopter sees. But a lot of shelters are stuck with whatever template their website platform offers, and keeping pet listings updated across two systems is a pain that most volunteer-run organizations don't have time for.

The SDK lets you build exactly what you want — or hire someone to build it — and have it stay in sync with PawPlacer automatically. Update a pet's status in PawPlacer and it's reflected on your website. Add a new animal and it shows up in your listing. No double entry, no copy-pasting, no forgetting to update the website for three weeks.

The full docs, OpenAPI spec, and example code are linked from the package readme on npm. Install it, grab an API key, and see what you can build.

Manage your rescue with PawPlacer

Free for small shelters, rescues, and foster networks. No credit card, no trial period, no catch.

Start FreeSee Features

More from the blog

Cover for Free Shelter Software in 2026: What Actually Exists

Free Shelter Software in 2026: What Actually Exists

Cover for AI-Powered Pet Adoption Matching: How We Built It and How It Works

AI-Powered Pet Adoption Matching: How We Built It and How It Works

Cover for How to Write Pet Adoption Profiles That Actually Get Animals Adopted

How to Write Pet Adoption Profiles That Actually Get Animals Adopted

PawPlacer

© Copyright 2026 PawPlacer. All Rights Reserved.

Contact
  • Email
About
  • About Us
  • Funding Philosophy
  • Careers
  • FAQ
  • Pricing
  • Blog
  • Changelog
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy