Gallery Submissions API

A write-only REST API for sharing real products and services purchased through OneCheckout. Submissions are private: they are content-screened and reviewed internally, and a curated subset may later appear in the OneCheckout gallery. There is no public feed.

base endpoint

overview

How it works

  1. 1

    Submit a purchase

    POST the product details to the endpoint. No API key required; the endpoint is public, CORS-enabled, and write-only.

  2. 2

    Acknowledged privately

    You receive a generic confirmation. Submissions are stored privately; the API never reveals whether an item was screened, is pending, approved, or rejected.

  3. 3

    Internal review

    Every submission is content-screened and reviewed by our team. All moderation happens internally and is never exposed through the API.

  4. 4

    May be curated into the gallery

    We may later feature a curated subset in the OneCheckout gallery, showing only limited, public-safe fields, never full last names, emails, or phone numbers.

endpoint

Submit a purchase

POST/api/gallery/submissions

Accepts a JSON body. Field names are accepted in both camelCase and snake_case. Every text field has a length limit and is safely truncated, so keep values concise (names ≤ 200 chars, each option ≤ 120 chars, description ≤ 2000 chars).

Required fields

FieldTypeDescription
productUrlreqstring (URL)

The product, service, or offering URL that was purchased.

e.g. "https://www.nike.com/t/air-force-1"

sellerNamereqstring

Name of the seller, brand, or merchant.

e.g. "Nike"

productNamereqstring

Name of the product or service.

e.g. "Air Force 1 '07"

pricereqnumber

Purchase price. Alias: priceAmount. Must be a non-negative number; stored to 2 decimals.

e.g. 115.00

submitterEmailreqstring (email)

Contact email for the caller. Must contain @. Never shown publicly.

e.g. "dev@yourapp.com"

submitterPhonereqstring (E.164)

Contact phone for the caller. US & Canada only: must be "+1" followed by 10 digits. Common separators (spaces, dashes, parens, dots) are stripped before validation. Never shown publicly.

e.g. "+14155550123" · "+1 (415) 555-0123"

Optional fields

FieldTypeDescription
rootUrlstring (URL)

Root URL of the site. Auto-derived from productUrl's origin when omitted.

e.g. "https://www.nike.com"

selectedOptionsstring[]

The chosen options as discrete strings: size, color, tier, seat, etc. List each option separately; the specific variant/SKU should be apparent from the options here. Each option max 120 chars, up to 24 options. A single string is also accepted and split on common separators.

e.g. ["White/White", "Men's size M 10 / W 11.5"]

quantityinteger

Whole number of units purchased (min 1).

e.g. 1

descriptionstring

Optional longer description (max 2000 chars).

currencystring (ISO 4217)

3-letter currency code. Defaults to USD.

e.g. "USD"

priceIntervalenum

Billing cadence for subscriptions: once, day, week, month, quarter, year. Defaults to once.

e.g. "month"

imageUrlstring (URL)

Product image URL. Send the highest-resolution image available; 600px wide or larger strongly preferred. Avoid tiny thumbnails.

e.g. "https://cdn.example.com/product-1200.png"

textPosterboolean

Set true when the image is a text-forward poster/card (a wordmark, plan card, event ticket, etc.) rather than a photographic product shot. Poster images are shown fully (contain-fit + centered) over a matching backdrop instead of being cropped to fill, so no artwork is cut off. Also accepts snake_case text_poster. Defaults to false.

e.g. true

logoUrlstring (URL)

A direct URL to the seller's own brand logo. Do not send third-party logo-service links; when a valid direct logo isn't available we resolve one ourselves.

categorystring

The product category. Use one of our standard categories whenever it applies; send the exact value shown in the category list. If your product is genuinely new, you can submit a custom value.

e.g. "apparel" · "saas" · "consumer services"

sourcePlatformstring

Where the buy button lived, e.g. the ad network, chat, or article.

e.g. "Pinterest ad" · "ChatGPT" · "The Verge"

mcpRequestobject | string (JSON)

A re-playable MCP request that lets others buy exactly this product. Send the JSON-RPC style request object (or a JSON string). Stored as-is for reference and never executed by us. Max 20,000 chars serialized.

e.g. { "method": "tools/call", "params": { "name": "checkout", "arguments": { "productUrl": "https://www.nike.com/t/air-force-1", "options": ["White/White", "M 10"] } } }

buyerDisplayFirstNamestring

Buyer's first name for public attribution (max 80 chars).

e.g. "Alex"

buyerDisplayLastInitialstring

Buyer's last initial only, never a full last name. Trimmed to a single initial.

e.g. "R"

purchasedAtstring (ISO 8601)

When the purchase happened.

e.g. "2026-07-02T18:30:00Z"

eventDatestring (YYYY-MM-DD)

Event start date for ticketed purchases. ALWAYS send this for tickets (category tickets/events): ticketed submissions without an event date are rejected in review, and any event whose date is today or in the past (evaluated in US Pacific time) is automatically removed so past events never appear. Bare calendar date only, no time or timezone. Also accepts snake_case event_date.

e.g. "2026-08-15"

submitterRefstring

Your own reference / partner id for this submission.

Content self-flag

Any truthy flag below forces the submission out of the public gallery, even if the automated screen passes. Use it to responsibly mark sensitive content.

FieldTypeDescription
nsfwboolean

Self-declare mature / sensitive content. Also accepts: mature, flagged, sensitive.

e.g. true

contentRatingstring

Set to "mature" to hold the item out of the public gallery.

e.g. "mature"

Example request

cURL
curl -X POST https://onecheckout.ai/api/gallery/submissions \
  -H "Content-Type: application/json" \
  -d '{
    "productUrl": "https://www.nike.com/t/air-force-1",
    "rootUrl": "https://www.nike.com",
    "sellerName": "Nike",
    "productName": "Air Force 1 '07",
    "submitterEmail": "dev@yourapp.com",
    "submitterPhone": "+14155550123",
    "selectedOptions": ["White/White", "Men's size M 10 / W 11.5"],
    "quantity": 1,
    "price": 115.00,
    "currency": "USD",
    "priceInterval": "once",
    "imageUrl": "https://static.nike.com/air-force-1-1200.png",
    "category": "apparel",
    "sourcePlatform": "Pinterest ad",
    "buyerDisplayFirstName": "Alex",
    "buyerDisplayLastInitial": "R",
    "purchasedAt": "2026-07-02T18:30:00Z"
  }'
JavaScript · fetch
const res = await fetch("https://onecheckout.ai/api/gallery/submissions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    productUrl: "https://www.netflix.com/premium",
    sellerName: "Netflix",
    productName: "Netflix Premium 4K",
    submitterEmail: "dev@yourapp.com",
    submitterPhone: "+1 (415) 555-0123",
    selectedOptions: ["Premium", "Ad-free", "4K UHD"],
    quantity: 1,
    price: 22.99,
    currency: "USD",
    priceInterval: "month",
    category: "streaming",
    sourcePlatform: "X promoted post",
  }),
})

const { id, message } = await res.json()
// The response is intentionally generic; no moderation status is returned.
JavaScript · ticketed event
// Ticketed event: always include eventDate (YYYY-MM-DD). Ticket art is
// usually a poster/card, so set textPoster: true so it isn't cropped.
const res = await fetch("https://onecheckout.ai/api/gallery/submissions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    productUrl: "https://tickets.example-arena.com/e/aurora-live",
    sellerName: "Aurora Live",
    productName: "Aurora: World Tour",
    category: "tickets",
    eventDate: "2026-08-15", // event START date, US Pacific is used for expiry
    selectedOptions: ["Section 104", "Row 12", "2 seats"],
    quantity: 2,
    price: 189.5,
    currency: "USD",
    imageUrl: "https://cdn.example-arena.com/aurora-poster.png",
    textPoster: true, // show the full poster, don't crop it
    submitterEmail: "dev@yourapp.com",
    submitterPhone: "+14155550123",
  }),
})
// Events dated today or earlier (US Pacific) are auto-removed in nightly review;
// ticketed events sent without eventDate are rejected.

Responses

201 Created. Stored as pending (or rejected if the screen tripped).
201 Created
{
  "id": "b1c2d3e4-....",
  "message": "Received. Thank you, your submission will be reviewed."
}
422 Validation failed. Missing or invalid fields.
422 Unprocessable
{
  "error": "Validation failed",
  "details": [
    "productUrl is required and must be a valid http(s) URL",
    "sellerName is required",
    "submitterEmail must contain @",
    "submitterPhone must be \"+1\" followed by 10 digits (US & Canada only)"
  ]
}
429 Rate limit exceeded. Includes a Retry-After header (seconds).
429 Too Many Requests
{
  "error": "Daily limit reached. Each email and phone is capped at 50 requests per day.",
  "retryAfter": 43200
}
  • 400 Invalid JSON body.

Rate limits

Limits are enforced per identity: both your submitterEmail and submitterPhone are metered independently, so rotating one while reusing the other does not reset your quota.

  • 50 requests per day per email and per phone (resets at 00:00 UTC).
  • 1 request per second per email and per phone.
  • Requests that fail validation (422) do not count against your quota.

taxonomy

Categories

This is a normalized list of standard categories. Send the exact value shown for the category field whenever one applies, always preferring the most specific fit. Use shopping only as a last-resort catch-all for a physical purchase that fits no more specific category. If your product is genuinely new and none of these fit, you can submit a custom value; anything unrecognized is shown generically in the gallery.

accessories
Accessories

Bags, belts, watches, and small goods.

api
API & Developer Services

Developer APIs, SDKs, and usage-based developer platforms.

apparel
Apparel

Clothing and wearables.

automotive
Automotive

Vehicles, parts, and accessories.

beauty
Beauty & Personal Care

Cosmetics, skincare, and grooming.

books media
Books & Media

Physical books, print, and physical media.

cloud services
Cloud & Infrastructure

Cloud hosting, storage, and infrastructure.

consumer services
Consumer Services

Non-physical consumer services and memberships.

digital services
Digital Services

Digital-only services and online tools.

electronics
Electronics

Devices, gadgets, and hardware.

events
Events

Conferences, shows, and experiences.

financial services
Financial Services

Fintech, banking, and financial service subscriptions.

fitness
Fitness

Fitness gear, equipment, and training products.

food beverage
Food & Beverage

Food, drink, and consumables.

footwear
Footwear

Shoes, sneakers, and boots.

furniture
Furniture

Furniture and large home items.

gaming
Gaming (Digital)

Digital games, in-game goods, and game subscriptions.

health wellness
Health & Wellness

Supplements and physical wellness products.

home
Home & Kitchen

Homeware, kitchen, and household goods.

insurance
Insurance

Insurance policies and coverage plans.

jewelry
Jewelry

Jewelry and fine accessories.

memberships
Memberships

Membership and community access plans.

online courses
Online Courses & Education

Courses, cohorts, and digital learning.

pet
Pet Supplies

Products for pets and animals.

saas
SaaS

Software-as-a-service products and platforms.

shopping
Shopping

General ecommerce purchases that don't fit a more specific category.

software
Software

Downloadable or licensed software and apps.

sporting goods
Sporting Goods

Sports, fitness, and outdoor gear.

streaming
Streaming & Media

Streaming video, music, and media subscriptions.

subscriptions
Subscriptions

Recurring subscription plans not covered by another bucket.

telecom
Telecom & Connectivity

Mobile, internet, and connectivity plans.

tickets
Tickets

Event tickets (usually poster/card artwork).

toys games
Toys & Games

Physical toys and tabletop games.

travel
Travel

Flights, stays, and travel bookings.

policy

Submissions are private

This is a write-only API. There is no public endpoint to read, list, or browse submissions, and the submit response never discloses moderation state: you cannot tell whether an item was screened, is pending, approved, or rejected.

What may become public later

We may later feature a hand-curated subset of submissions in the OneCheckout gallery. That surface will expose only limited, public-safe fields, never full last names, email addresses, or phone numbers. Contact details you provide are used solely for follow-up and abuse prevention.

policy

Moderation & content policy

Every submission is content-screened and reviewed internally before it could ever be considered for the gallery. Moderation decisions are made entirely on our side and are not exposed through the API.

Content policy

Explicit, adult, illegal, weapons, hateful, or otherwise sensitive products are automatically rejected and will not be published. We also honor your self-declared content flags. Submitting content that violates this policy may result in your submissions being blocked.