Developers

Stallion API

Load the stallions a station publishes on OneTrot straight into its website: pedigree, photos, stud fees, texts and the booking link. The station maintains everything once, in OneTrot, and the website is always up to date.

Overview

Base URL
https://onetrot.com/api/public/v1
Authentication
None. The API is read-only and serves only what the station publishes on its public OneTrot pages.
Format
JSON (UTF-8). Every successful response wraps its payload in data.
Version
v1, part of the URL. Within v1 fields are only ever added.
OpenAPI
Machine-readable description for code generators and tools such as Postman: https://onetrot.com/api/public/v1/openapi.json

Quick start

Every station is addressed by the slug from its booking link: …/de/book/gestuet-sonnenfeld has the slug gestuet-sonnenfeld. The examples on this page use Gestüt Sonnenfeld, a fictional demo station; replace its slug with your station's. This call returns all its public stallions:

curl "https://onetrot.com/api/public/v1/stables/gestuet-sonnenfeld/stallions?locale=en"

Concepts

Slugs are your keys

A station's slug and a stallion's slug are the last parts of the booking link. A stallion's slug is unique within its station and stays the same when the stallion is renamed, so store it as the key in your CMS.

Language

Add locale=de or locale=en (default: de). Labels such as breed and colour are translated. Texts are written by the station: if a stallion has no copy in the requested language, you get the other language and texts.locale tells you which one you received.

Booking links

Point every "Order semen" button at links.booking: the form opens with the right stallion selected. Please link it (same tab or new tab) instead of embedding it in an iframe: sign-in and payment work reliably only in their own window.

Which stallions are included

Only stallions the station has set to active and public, exactly as on its OneTrot catalogue page. When a stallion disappears from the list, the station no longer offers it: hide it on the website. An old booking link to it still works and opens the station's stallion overview.

Prices

All amounts are integers in euro cents, net and gross, gross with 7 % VAT as on the OneTrot catalogue. offers holds one entry per bookable option (fresh semen, frozen semen, natural cover), each with its fees: initial is due at booking, pregnancy once the mare is confirmed in foal, redelivery for every further frozen shipment. formatted is ready to display. priceNote is the station's own note, such as "per straw".

Photos and videos

Image URLs point to OneTrot's image storage and remain valid; you may hotlink them or copy them into your media library. focalPoint is the crop the station chose, as a CSS object-position value: use it so a cropped photo shows the horse and not the background. videos are YouTube URLs.

Caching and limits

Responses may be cached for 5 minutes. Every response carries an ETag: send it back in If-None-Match and you get 304 Not Modified while nothing has changed. The limit is 120 requests per minute per IP address, generous for a sync job, too small for one call per page view.

Endpoints

List a station's stallions

GET/stables/{stableSlug}/stallions

All stallions the station publishes, sorted by name. Not paginated: a station stands tens of stallions, so you always get the full list in one call.

Parameters

stableSlugpath · string · required
The station's slug, as in its booking link.
localequery · string · optional
de or en. Default de.

Request

curl "https://onetrot.com/api/public/v1/stables/gestuet-sonnenfeld/stallions?locale=en"

Response

200 OK · application/json
{
  "data": [
    {
      "id": "5f0c2a7e-1d4b-4c6a-9e2f-7b3d8a1c6e90",
      "slug": "soprano-sonnenfeld",
      "name": "Soprano Sonnenfeld",
      "updatedAt": "2026-10-20T09:12:44.000Z",
      "breed": {
        "key": "oldenburg",
        "label": "Oldenburg"
      },
      "color": {
        "key": "black",
        "label": "Black"
      },
      "wffs": {
        "key": "negative",
        "label": "WFFS Negative (N/N)"
      },
      "yearOfBirth": 2018,
      "heightCm": 172,
      "ueln": "276431017232512",
      "breeder": "Gestüt Sonnenfeld",
      "owner": null,
      "approvedFor": [
        "Verband der Züchter des Oldenburger Pferdes e.V.",
        "Hannoveraner Verband e.V."
      ],
      "texts": {
        "locale": "en",
        "tagline": "The stud's flagship stallion",
        "description": {
          "html": "<p>Soprano Sonnenfeld combines modern type and athletic ability.</p>",
          "text": "Soprano Sonnenfeld combines modern type and athletic ability."
        },
        "achievements": null,
        "characteristics": null,
        "priceNote": "Fresh semen: second instalment once the mare is in foal"
      },
      "pedigree": {
        "sire": {
          "name": "Sonnenkönig",
          "registrationNumber": "276431010012014",
          "breed": "Old",
          "award": null,
          "sire": {
            "name": "Royal Sun",
            "registrationNumber": null,
            "breed": "Han",
            "award": null,
            "sire": null,
            "dam": null
          },
          "dam": {
            "name": "Belle Étoile",
            "registrationNumber": null,
            "breed": null,
            "award": null,
            "sire": null,
            "dam": null
          }
        },
        "dam": {
          "name": "Donna del Sol",
          "registrationNumber": null,
          "breed": "Old",
          "award": null,
          "sire": {
            "name": "Diamantino",
            "registrationNumber": null,
            "breed": null,
            "award": null,
            "sire": null,
            "dam": null
          },
          "dam": {
            "name": "Fleur du Nord",
            "registrationNumber": null,
            "breed": null,
            "award": null,
            "sire": null,
            "dam": null
          }
        }
      },
      "media": {
        "hero": {
          "url": "https://chpvnflyhhdnaaugasjt.supabase.co/storage/v1/object/public/public/stallion-images/demo/soprano-sonnenfeld/hero.webp",
          "focalPoint": "50% 30%"
        },
        "gallery": [
          {
            "url": "https://chpvnflyhhdnaaugasjt.supabase.co/storage/v1/object/public/public/stallion-images/demo/soprano-sonnenfeld/1.webp",
            "focalPoint": null
          }
        ],
        "videos": []
      },
      "offers": [
        {
          "type": "fresh",
          "fees": [
            {
              "kind": "initial",
              "netCents": 50000,
              "grossCents": 53500,
              "vatRatePercent": 7,
              "currency": "EUR",
              "formatted": "535,00 €"
            },
            {
              "kind": "pregnancy",
              "netCents": 50000,
              "grossCents": 53500,
              "vatRatePercent": 7,
              "currency": "EUR",
              "formatted": "535,00 €"
            }
          ]
        },
        {
          "type": "frozen",
          "fees": [
            {
              "kind": "initial",
              "netCents": 90000,
              "grossCents": 96300,
              "vatRatePercent": 7,
              "currency": "EUR",
              "formatted": "963,00 €"
            },
            {
              "kind": "redelivery",
              "netCents": 30000,
              "grossCents": 32100,
              "vatRatePercent": 7,
              "currency": "EUR",
              "formatted": "321,00 €"
            }
          ]
        }
      ],
      "links": {
        "booking": "https://onetrot.com/en/book/gestuet-sonnenfeld/soprano-sonnenfeld",
        "catalogue": "https://onetrot.com/en/catalogue/gestuet-sonnenfeld/soprano-sonnenfeld",
        "vetCheck": null
      }
    },
    "..."
  ]
}

Get one stallion

GET/stables/{stableSlug}/stallions/{stallionSlug}

The same object as in the list, for one stallion. 404 when the stallion does not exist or is not public.

Parameters

stableSlugpath · string · required
The station's slug, as in its booking link.
stallionSlugpath · string · required
The stallion's slug, as in its booking link.
localequery · string · optional
de or en. Default de.

Request

curl "https://onetrot.com/api/public/v1/stables/gestuet-sonnenfeld/stallions/soprano-sonnenfeld?locale=en"

Response

200 OK · application/json
{
  "data": {
    "id": "5f0c2a7e-1d4b-4c6a-9e2f-7b3d8a1c6e90",
    "slug": "soprano-sonnenfeld",
    "name": "Soprano Sonnenfeld",
    "updatedAt": "2026-10-20T09:12:44.000Z",
    "breed": {
      "key": "oldenburg",
      "label": "Oldenburg"
    },
    "color": {
      "key": "black",
      "label": "Black"
    },
    "wffs": {
      "key": "negative",
      "label": "WFFS Negative (N/N)"
    },
    "yearOfBirth": 2018,
    "heightCm": 172,
    "ueln": "276431017232512",
    "breeder": "Gestüt Sonnenfeld",
    "owner": null,
    "approvedFor": [
      "Verband der Züchter des Oldenburger Pferdes e.V.",
      "Hannoveraner Verband e.V."
    ],
    "texts": {
      "locale": "en",
      "tagline": "The stud's flagship stallion",
      "description": {
        "html": "<p>Soprano Sonnenfeld combines modern type and athletic ability.</p>",
        "text": "Soprano Sonnenfeld combines modern type and athletic ability."
      },
      "achievements": null,
      "characteristics": null,
      "priceNote": "Fresh semen: second instalment once the mare is in foal"
    },
    "pedigree": {
      "sire": {
        "name": "Sonnenkönig",
        "registrationNumber": "276431010012014",
        "breed": "Old",
        "award": null,
        "sire": {
          "name": "Royal Sun",
          "registrationNumber": null,
          "breed": "Han",
          "award": null,
          "sire": null,
          "dam": null
        },
        "dam": {
          "name": "Belle Étoile",
          "registrationNumber": null,
          "breed": null,
          "award": null,
          "sire": null,
          "dam": null
        }
      },
      "dam": {
        "name": "Donna del Sol",
        "registrationNumber": null,
        "breed": "Old",
        "award": null,
        "sire": {
          "name": "Diamantino",
          "registrationNumber": null,
          "breed": null,
          "award": null,
          "sire": null,
          "dam": null
        },
        "dam": {
          "name": "Fleur du Nord",
          "registrationNumber": null,
          "breed": null,
          "award": null,
          "sire": null,
          "dam": null
        }
      }
    },
    "media": {
      "hero": {
        "url": "https://chpvnflyhhdnaaugasjt.supabase.co/storage/v1/object/public/public/stallion-images/demo/soprano-sonnenfeld/hero.webp",
        "focalPoint": "50% 30%"
      },
      "gallery": [
        {
          "url": "https://chpvnflyhhdnaaugasjt.supabase.co/storage/v1/object/public/public/stallion-images/demo/soprano-sonnenfeld/1.webp",
          "focalPoint": null
        }
      ],
      "videos": []
    },
    "offers": [
      {
        "type": "fresh",
        "fees": [
          {
            "kind": "initial",
            "netCents": 50000,
            "grossCents": 53500,
            "vatRatePercent": 7,
            "currency": "EUR",
            "formatted": "535,00 €"
          },
          {
            "kind": "pregnancy",
            "netCents": 50000,
            "grossCents": 53500,
            "vatRatePercent": 7,
            "currency": "EUR",
            "formatted": "535,00 €"
          }
        ]
      },
      {
        "type": "frozen",
        "fees": [
          {
            "kind": "initial",
            "netCents": 90000,
            "grossCents": 96300,
            "vatRatePercent": 7,
            "currency": "EUR",
            "formatted": "963,00 €"
          },
          {
            "kind": "redelivery",
            "netCents": 30000,
            "grossCents": 32100,
            "vatRatePercent": 7,
            "currency": "EUR",
            "formatted": "321,00 €"
          }
        ]
      }
    ],
    "links": {
      "booking": "https://onetrot.com/en/book/gestuet-sonnenfeld/soprano-sonnenfeld",
      "catalogue": "https://onetrot.com/en/catalogue/gestuet-sonnenfeld/soprano-sonnenfeld",
      "vetCheck": null
    }
  }
}

Get the station

GET/stables/{stableSlug}

Name, address, contact and the station's booking link (the stallion picker), for a contact block or the general "Order semen" button.

Parameters

stableSlugpath · string · required
The station's slug, as in its booking link.
localequery · string · optional
de or en. Default de.

Request

curl "https://onetrot.com/api/public/v1/stables/gestuet-sonnenfeld?locale=en"

Response

200 OK · application/json
{
  "data": {
    "slug": "gestuet-sonnenfeld",
    "name": "Gestüt Sonnenfeld",
    "address": {
      "line1": "Sonnenweg 1",
      "line2": null,
      "postalCode": "49377",
      "city": "Vechta",
      "country": "DE"
    },
    "contact": {
      "email": "info@gestuet-sonnenfeld.de",
      "phone": "+494441000000"
    },
    "links": {
      "booking": "https://onetrot.com/en/book/gestuet-sonnenfeld",
      "catalogue": "https://onetrot.com/en/catalogue/gestuet-sonnenfeld"
    }
  }
}

Example response, shortened: the pedigree shows two of four generations and the gallery one photo.

OpenAPI description

GET/openapi.json

This API as an OpenAPI 3.1 document.

The stallion object

Every field is always present; a value the station has not entered is null (or an empty list).

idstring (uuid)
Permanent id of the stallion.
slugstring
The stallion's slug; unique within the station, unchanged on rename. Use it as your key.
namestring
Name as the station writes it.
updatedAtstring | null
Last change to the stallion record (ISO 8601).
breed{ key, label } | null
Breed: key plus label in the requested language.
color{ key, label } | null
Colour: key plus label.
wffs{ key, label } | null
WFFS status: key plus label.
yearOfBirthinteger | null
Year of birth.
heightCminteger | null
Height at the withers in cm.
uelnstring | null
UELN (life number).
breederstring | null
Breeder.
ownerstring | null
Owner.
approvedForstring[]
Names of the breeding associations the stallion is approved for.
texts.locale"de" | "en" | null
Language of the texts actually returned (de or en); null when the stallion has no texts.
texts.taglinestring | null
Short one-liner, such as "One of a kind".
texts.description, .achievements, .characteristics{ html, text } | null
Long texts as sanitized HTML (html) and as plain text (text).
texts.priceNotestring | null
The station's note on the price.
pedigree{ sire, dam } | null
Pedigree up to four generations: every node has name, registrationNumber, breed, award and again sire and dam. An unknown ancestor is null, or a node with name null when ancestors above it are known.
media.hero{ url, focalPoint } | null
Main photo with focalPoint.
media.gallery{ url, focalPoint }[]
Further photos, in the station's order.
media.videosstring[]
YouTube URLs.
offers[]{ type, fees }
One entry per bookable option: type is fresh, frozen or natural_cover.
offers[].fees[]{ kind, netCents, grossCents, ... }
The option's fees: kind (initial, pregnancy, redelivery), netCents, grossCents, vatRatePercent, currency, formatted.
links.bookingstring
Booking page with this stallion selected. Your "Order semen" button.
links.cataloguestring
The stallion's public OneTrot page.
links.vetCheckstring | null
Link to the stallion's veterinary report, if the station provides one.

Errors

Errors answer with an HTTP status and a JSON body whose error object holds code and message:

400invalid_locale
locale is neither de nor en.
404not_found
The station or stallion does not exist or is not public.
429rate_limited
More than 120 requests per minute from your IP address. Retry later and cache.
500internal
An error on our side. The response carries an incidentId: please quote it when you contact us.
404 Not Found
{
  "error": {
    "code": "not_found",
    "message": "No public stallion \"unknown\" at \"gestuet-sonnenfeld\"."
  }
}

Versioning and support

v1 (October 2026): first release. Within v1 we only add fields, so ignore fields you do not know. A rename or removal would ship as /v2, announced in advance.

Questions or a field you are missing? Write to info@onetrot.com