This page is for the person who builds the farm's website. It is the long form of the For developers panel on the herd page in AlpacaKeep. If you are the farmer, the herd page article is the one you want.
Preview. Fields are only ever added, never renamed or removed. Tell us before you build something large on it.
What it is
Two read-only JSON addresses with the same data the herd widget shows. No key,
no sign-up, callable straight from a browser (Access-Control-Allow-Origin: *).
Use them when the widget's look is not close enough and you want to draw the
herd yourself, or when each animal page on your site must be indexed by
search engines. The widget is an iframe, so search engines read only the text
of your own page around it; a page you render from this data is fully yours.
GET https://www.alpacakeep.com/api/public/v1/farm/<farm-slug>/herd
GET https://www.alpacakeep.com/api/public/v1/animal/<animal-slug>
The farmer has to switch this on first. It is off by default. In
AlpacaKeep: Marketplace → Website widget → Set up the herd page → For
developers → Turn on data access. Until then both addresses answer 404,
while the widget keeps working.
The farm slug is shown in that panel. Every animal in the herd list carries
its own slug; put that into the second address.
Options
Anything else in the query string is refused: an unknown option, the same
option twice, or a value outside the table (page=0, page=51, page=02,
lang=fr, departed=true) answers 400 with {"error":"bad_request"}.
Do not add cache-busting parameters.
The herd list
{
"version": 1,
"farm": { "name": "Monviso Alpaca", "public_slug": "monviso", "country": "IT", "logo_url": null },
"composition": [ { "stage": "breeding_f", "count": 14 }, { "stage": "stud", "count": 2 } ],
"total": 31,
"page": 1,
"page_size": 100,
"animals": [
{
"slug": "luna-7k3f9q",
"name": "Luna",
"show_name": "Monviso Luna",
"display_name": "Monviso Luna",
"species": "alpaca",
"sex": "female",
"dob": "2021-05-15",
"life_stage": "breeding_f",
"fiber_type": "Huacaya",
"color_primary": "Light Fawn",
"departed": null,
"sale_url": null,
"photo": { "src": "https://www.alpacakeep.com/_next/image?url=…&w=384&q=75", "srcset": "… 384w, … 640w, … 828w" }
}
],
"labels": {
"life_stage": { "breeding_f": "Fattrici", "stud": "Stalloni", "…": "…" },
"sex": { "male": "Maschio", "female": "Femmina", "unknown": "Sconosciuto" },
"departed": { "moved": "Trasferito", "deceased": "Deceduto" }
}
}
display_nameis what to print: the registered name when there is one, else the name.life_stageis one ofcria_f,young_f,breeding_f,adult_f,cria_m,young_m,stud,adult_m,gelding,unknown(adult_fis an adult female the farm does not breed). Translate it throughlabels.life_stage; do not hard-code the words.compositionlists every stage in display order (zero counts included), ready for a legend or filter buttons. It counts the animals on this page, not the whole herd (totalis the whole herd). For a herd of up to 100 animals the two are the same; past that, add the pages up yourself.departedisnull,"moved"or"deceased".photoisnullwhen the animal has none. Putsrcandsrcseton an<img>together with asizesattribute that matches your layout. The URLs are already resized and compressed; never link to anything else.sale_urlis the animal's public sale page when it is listed for sale, elsenull.
One animal
The answer is { "version": 1, "farm": { … }, "animal": { … }, "labels": { … } }, with farm and labels exactly as in the herd list. The animal object has everything a card has, plus:
{
"bloodline": "Accoyo",
"color_secondary": null,
"markings": null,
"eye_color": "brown",
"height_cm": 90,
"coi_percent": 3.1,
"pedigree": {
"sire": "Monviso Orion", "dam": "Monviso Nuvola",
"paternal_grandsire": "Atlas", "paternal_granddam": "Stella",
"maternal_grandsire": null, "maternal_granddam": null,
"gen3": { "SSS": "Titan", "SSD": null, "SDS": null, "SDD": null, "DSS": null, "DSD": null, "DDS": null, "DDD": null }
},
"pedigree_colors": {
"sire": "Light Fawn", "dam": "White",
"paternal_grandsire": "Dark Brown", "paternal_granddam": null,
"maternal_grandsire": null, "maternal_granddam": null,
"gen3": { "SSS": null, "SSD": null, "SDS": null, "SDD": null, "DSS": null, "DSD": null, "DDS": null, "DDD": null }
},
"pedigree_colors_secondary": {
"sire": "White", "dam": null,
"paternal_grandsire": null, "paternal_granddam": null,
"maternal_grandsire": null, "maternal_granddam": null,
"gen3": { "SSS": null, "SSD": null, "SDS": null, "SDD": null, "DSS": null, "DSD": null, "DDS": null, "DDD": null }
},
"gallery": [ { "src": "https://…", "srcset": "…", "caption": null } ],
"fiber_reports": [ { "date": "2026-05-01", "afd_micron": 19.4, "sd": 4.1, "cv": 21.1, "comfort_factor": 97.8, "spin_fineness": null, "curvature_deg_per_mm": null, "lab_name": "…", "coarse_edge_micron": 23.6, "staple_length_mm": 95 } ],
"show_highlights": [ { "show_name": "National Show", "date": "2023-09-10", "show_end_date": "2023-09-11", "show_type": "halter", "class": "Huacaya female light", "colour_class": "Light", "sanctioning_body": "BAS", "placement_rank": 1, "entries_in_class": 9, "placing_status": null, "championship_award": "color_champion", "award_title": null, "score": null, "prize_type": "rosette", "ribbon_color": "blue", "placement": null, "photo_url": "https://…" } ]
}
pedigree.gen3is the great-grandparents, keyed by the path from the animal:S= sire,D= dam, soSDSis the sire's dam's sire.null= unknown.pedigree_colorshas exactly the keys ofpedigreeand holds each ancestor's coat colour as the farm recorded it ("Light Fawn", "Medium Grey"). It isnullwhen the ancestor is known only by name (typed in, not an animal on the farm) or has no colour recorded. Colour names are not translated.pedigree_colors_secondaryhas the same keys and holds the second colour of a two-coloured animal (nullfor a solid one); show the two together as "Light Fawn / White". Added October 2026.coi_percentis the inbreeding coefficient in percent. It isnullwhen it cannot be worked out from the recorded parents, or when the farm chose not to publish it.fiber_reportsis newest first, at most ten. It is an empty list when the farm chose not to publish fiber results; treat empty as "show nothing". Per report, any number may benullwhen the lab did not measure it:afd_micronis the average fiber diameter andsdits spread, both in microns;cvissdrelative toafd_micron, in percent.comfort_factoris the share of fibers at or under 30 microns, in percent. The share OVER 30 microns is100 - comfort_factor; it is not a separate field, so work it out when you want to show it.coarse_edge_micron(CEM) is the average diameter of the coarsest 5% of the fibers, in microns.staple_length_mmis the staple length the lab measured, in millimetres. Both added October 2026.
galleryexcludes the profile photo (that one isphoto).show_highlightsholds at most twelve results: the animal's STRONGEST, strongest first. Order: champion titles (Supreme Champion, Best in Show and Champion of Champions first, then Grand Champion, Best in Colour and Best of Breed, then Color, Age, Progeny and Performance Champion), then reserve titles (Reserve Supreme / Best in Show / Grand / Color Champion and the others), then other awards (Judge's Choice, Best Bred and Owned, Best Home-Country Bred, a specialty award) - each only when won in the animal's own class, a group class such as Get of Sire does not count - then the best placing, then the highest fleece score out of 100, then the newestdate. Until September 2026 the list was newest first only, so do not assume the first result is the most recent: sort bydateyourself if you need a timeline. The list is capped, so do not count results from it: an animal with a long show career has more than twelve. It is an empty list when the farm chose not to publish show results. Per result:placement_rankis the class placing (1 = first) andentries_in_classthe class size, either may benull.placing_statusis set only when there is no placing:"highly_commended","not_placed","withdrawn"or"disqualified".championship_awardis a title such as"color_champion","grand_champion","supreme_champion","best_in_show"or a reserve ("reserve_color_champion", …), elsenull. It is the title's LEVEL; new values may be added over time (for example"age_champion","best_in_colour","progeny_champion","performance_champion", their reserves,"reserve_best_in_show","reserve_champion_of_champions","best_bred_and_owned"and"best_home_country_bred"), so show an unknown value as a title rather than dropping the result.award_titleis the title exactly as the show printed it ("Beste Stute der Show", "Grand Champion White Male"), ornullwhen the farm did not type one. When it is set, show it instead of a name forchampionship_award. It is only ever set beside achampionship_award. One animal can hold several titles at one show: each is its own result.scoreis a fleece score, normally out of 100 (fleece classes), elsenull. Some older records hold a score on another scale: write "/100" only beside a score between 0 and 100.prize_typeis what was handed over:"rosette","ribbon","sash","trophy","medal","certificate","plaque","prize_money","banner"or"other".show_end_dateis the last day of a show that ran over several days,nullfor a one-day show.photo_urlis the farm's own photo of this result (the rosette, the ring), already resized, ornull.placementis free text from older records; show it only when the fields above are empty. Class names, show names andplacementare the farm's own words and are not translated.
- Numbers are plain JSON numbers with a dot. Format them for your reader
(
19,4in Italian and German).
What is never in it
Prices, availability, health tests (BVDV, DNA), pregnancy, notes, documents,
registration numbers, purchase data, anything financial. If you need a price,
link to sale_url.
Rules
- Stable.
versionis 1. Fields are only ever added, never renamed or removed. Ignore keys you do not know. A list of values such aslife_stagecan gain a new value; show it with its word fromlabels. - Permanent animal slugs. An animal's slug never changes, and the animal
address keeps answering after a sale, a transfer or a death (with
departedset), so a printed QR code keeps working. It answers404with{"error":"not_found"}only when the farmer hides the animal, turns the herd page or the data access off, the farm's plan no longer includes the herd page, or the slug never existed. Handle a404and a500on your side: show your own page without the data rather than an error. - Five-minute cache. A change in AlpacaKeep can take up to five minutes to appear. Do not add a cache-busting parameter; cache on your side instead if you render on a server.
- Fair use. Heavy automated traffic is slowed down per IP address, and we may switch data access off for a site that abuses it. One call per page view is fine; a loop over every animal on every page view is not: the herd list already carries what a grid needs.
- Your visitors' privacy. If the page loads the data or the photos in the visitor's browser, as the example below does, the browser contacts AlpacaKeep directly and our servers see its IP address, just as with the website widget, so the site's privacy notice should mention it.
- Credit. A page built on this data shows a visible link reading
"Data by AlpacaKeep" to
https://www.alpacakeep.com. The link may carryrel="nofollow". The marketplace listing terms apply to the farm.
Minimal example
<div id="herd"></div>
<script>
fetch('https://www.alpacakeep.com/api/public/v1/farm/monviso/herd?lang=it')
.then((r) => r.json())
.then(({ animals, labels }) => {
const el = document.getElementById('herd');
for (const a of animals) {
const card = document.createElement('a');
card.href = '/gregge/' + a.slug;
if (a.photo) {
const img = document.createElement('img');
img.src = a.photo.src;
img.srcset = a.photo.srcset;
img.sizes = '(min-width: 700px) 25vw, 50vw';
img.alt = a.display_name;
img.loading = 'lazy';
card.appendChild(img);
}
card.appendChild(document.createTextNode(a.display_name + ' · ' + labels.life_stage[a.life_stage]));
el.appendChild(card);
}
});
</script>
<a href="https://www.alpacakeep.com" rel="nofollow">Data by AlpacaKeep</a>