Back to home

API Documentation

Generate Pinterest-ready pins programmatically. Plug PinImage into Make.com, Zapier, n8n, or any HTTP client to automate your visual content workflow.

AuthenticationEndpointTry itcURLNode.jsPythonZapierMake.comErrors

Authentication

All requests require a Bearer token in the Authorization header. Generate a key from the API Keys page — keys start with pk_live_ and are shown only once.

Authorization: Bearer pk_live_xxxxxxxxxxxx

Endpoint

POST https://pinimagestudio.com/api/public/v1/pins

Request body (JSON)

FieldTypeDescription
templatestringOne of: classic, bold-quote, magazine, minimal, banner, framed, polaroid, ticket, sidebar, duotone, sticker, grid, cover, ribbon, circle
titlestringThe pin headline (max 200 characters).
image_urlstringDirect URL to a JPEG or PNG image file. Must link to the image itself, not a webpage. CDN and redirect URLs are supported.
brand_colorstringHex color, e.g. #7C3AED. Defaults to brand purple.

Response (200 OK)

{
  "id": "8f3d...",
  "url": "https://.../pin.png",
  "usage": { "used": 12, "limit": 500 }
}

Try it now

Paste a key, tweak the body, and send a real request. The key never leaves your browser.

cURL example

curl -X POST https://pinimagestudio.com/api/public/v1/pins \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "classic",
    "title": "10 Cozy Fall Recipes",
    "image_url": "https://images.pexels.com/photos/1793035/pexels-photo-1793035.jpeg?auto=compress&cs=tinysrgb&w=1200",
    "brand_color": "#7C3AED"
  }'

Node.js / JavaScript

const res = await fetch("https://pinimagestudio.com/api/public/v1/pins", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template: "classic",
    title: "10 Cozy Fall Recipes",
    image_url: "https://example.com/photo.jpg",
    brand_color: "#7C3AED",
  }),
});
const { url } = await res.json();
console.log("Pin URL:", url);

Python

import requests

resp = requests.post(
    "https://pinimagestudio.com/api/public/v1/pins",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "template": "classic",
        "title": "10 Cozy Fall Recipes",
        "image_url": "https://example.com/photo.jpg",
        "brand_color": "#7C3AED",
    },
)
print(resp.json()["url"])

Zapier integration

  1. In your Zap, add a new action and choose Webhooks by Zapier → POST.
  2. URL:
    https://pinimagestudio.com/api/public/v1/pins
  3. Payload Type: JSON
  4. Headers: add a row with key Authorization and value Bearer YOUR_API_KEY. Add another row Content-Type = application/json.
  5. Data fields: add template, title, image_url, brand_color — map values from your trigger step.
  6. Test the step. Use the returned url in the next step (Pinterest, Buffer, Sheets…).

Note: image_url must be a direct image file URL (e.g. your WordPress featured image URL), not a link to a webpage.

Make.com / n8n integration

  1. Add an HTTP → Make a request module.
  2. URL:
    https://pinimagestudio.com/api/public/v1/pins
  3. Method: POST
  4. Headers: two entries — Authorization: Bearer YOUR_API_KEY and Content-Type: application/json.
  5. Body type: Raw, Content type JSON (application/json).
  6. Request content:
    {
      "template": "classic",
      "title": "{{1.title}}",
      "image_url": "{{1.image_url}}",
      "brand_color": "#7C3AED"
    }
  7. Parse the response as JSON and use url downstream.

Note: image_url must be a direct image file URL (e.g. your WordPress featured image URL), not a link to a webpage.

Errors & rate limits

StatusMeaning
400Bad RequestInvalid or missing fields in the body.
401UnauthorizedMissing or invalid API key.
402Plan requiredAPI access requires a Pro or Agency plan (free plan users get this error).
429Rate limited / quota exceededTwo cases — check the "error" field: "rate_limited" (over 60 requests/min, slow down and retry) or "quota_exceeded" (monthly limit reached — response includes used, limit, reset_at).
500Server errorSomething went wrong on our side. Retry with exponential backoff.

Need a higher limit? See pricing.