Can you download FDA’s list of warning letters? You get 1,000 rows, and not the same 1,000 twice
Reference page · published 2026-10-07
Short answer: you can download a file, but the file is not the list, and it is not even a stable file. FDA’s warning letter page offers a spreadsheet export. Press it and you get exactly 1,000 rows — every time, no matter what. The real index is bigger than that, and nothing in the file, the filename, or the page you downloaded it from tells you that anything was left out. We pressed the download links thirteen different ways on October 3, 2026, pressed the plain version again on October 5 along with twenty-two name searches, re-ran eight of those searches on October 6 to check two of our own spellings and the stability of the rest, and counted what came back each time.
The practical consequence is the one that matters here. This index keeps a dedicated record page for 22 companies. We looked for each of them in the plain download and then searched each one by name in the same search box. Three were in the download. Fifteen were missing from it and returned a letter of their own the moment we searched their name. If you had used the spreadsheet to check whether those fifteen vendors had ever received a warning letter, it would have shown you nothing for fifteen companies that have one.
And then there is the part we did not expect. The download we pulled on October 5 is a different file from the one we pulled on October 3 — different letters, a different date range, a different count of duplicates. Of our 22 tracked companies, the October 3 file contained eight and the October 5 file contained three, and the two files had no tracked company in common at all.
This page is about a mechanical problem, not a legal one. It matters here because this whole index rests on the idea that you can go read the primary record yourself instead of taking a vendor’s word for it. A download that quietly stops short is a bad foundation for that, and several of our own pages cite exports from this same tool. We say below which ones and what we think it does and does not change about them.
What the button is
FDA’s warning letters page runs on a sortable table. The page’s own configuration
names two download links. The first it calls exportUrl
, and it points at
/warning-letters/datatables-data?page&_format=xlsx. That is the ordinary
“export” control a reader would use. The second it calls batchExportUrl
, at the
same address with /batch/ inserted.
We fetched both, plus the export with a range of search terms and page numbers attached. Every file is archived. Here is the first thing we counted:
| What we asked for | Rows we got back |
|---|---|
| The export with no search term (the plain “download everything” case) | 1,000 |
The same, with page=0 through page=4 | 1,000 each time |
| The plain export again, two days later | 1,000 |
A search for misbranded drugs | 873 |
A search for research use only | 639 |
A search for Seatex | 2 |
A search that matches a few letters returns a few rows. A search that matches a lot of them returns 1,000 and stops. 1,000 is a ceiling, not a count.
The thousand rows are not the newest thousand
A cap would be much less of a problem if the file kept the most recent letters and dropped the old ones. You would at least know what you had. That is not what happens.
We checked whether the export is sorted at all. It is not — the Posted Date column runs in
no order, ascending or descending. The plain download we pulled on October 5 spans
January 5, 2021 to April 28, 2026. The newest letter in it is from April 28, 2026,
while a search for research use only run the same day returns letters posted as recently
as September 29, 2026.
That is a gap of 154 days — five months of the most recent enforcement activity, absent from the file with no notice. Both halves of that comparison were measured on the same day, which matters: an older download compared against a fresher search would have produced the same number for the wrong reason.
The newest letters are exactly the ones a person checking a vendor today would most want. The file is also missing a scattering of older letters, with no pattern we could find.
Press the same button twice and you get two different files
This is the finding we did not go looking for, and it is the one that changes how you should use the export.
We pulled the plain download on October 3 and again on October 5. Same address, no search term, nothing different about the request. Both came back with 1,000 rows. They are not the same 1,000.
| The plain download | October 3, 2026 | October 5, 2026 |
|---|---|---|
| Rows | 1,000 | 1,000 |
| Distinct letters | 989 | 995 |
| Repeated rows | 11 | 5 |
| Oldest letter | March 30, 2021 | January 5, 2021 |
| Newest letter | April 14, 2026 | April 28, 2026 |
| Of our 22 tracked companies, how many appear | 8 | 3 |
The two files share 192 letters. 797 letters are only in the October 3 file and 803 are only in the October 5 file. These are not two versions of one list with a few additions at the end. They are two largely different samples of the same index.
We had already seen both of these files on October 3, without understanding what we were looking
at. On that day we fetched the export six times with the page number set to nothing, 0, 1, 2, 3 and
4, and got two distinct sets of letters back: pages 0, 1 and 4 returned one set of
995, while the empty page number, page 2 and page 3 returned a different set of 989. Two days later,
the empty page number — the plain download, the one a reader actually gets — returned the
995 set instead. We checked that directly: the October 5 download is the same set of letters
as October 3’s page=0 request, and not the same set as its
page=2 request.
We do not know why the server behaves this way and we are not going to guess at it. What we can say from the measurements is narrow and sufficient: which thousand letters the download gives you is not fixed, and nothing in the file tells you which thousand you got. Two readers pressing the same button on different days can reach opposite conclusions about the same company and both be reading the file correctly.
A name search does not behave this way, and that is the main reason we recommend one. We re-sent three of our name searches a day later — for PureRawz, for Peptide Sciences and for Paradigm — and all three returned the same letters they had returned the day before. The files were not byte-for-byte identical, so something in them is regenerated on each request, but the rows were the same rows. A bulk download changed both what it contained and how it was built; a name search changed only how it was built. That is the difference between a tool you can cite and a tool you cannot.
There is one piece of identifying information in the file, and it is worth knowing about because
it is not where you would look. Neither download states a row total or a version anywhere in its
cells — but both carry a created timestamp in the workbook’s document
properties, and the two differ. The October 3 file records
2026-10-03 02:11:33 and the October 5 file records 2026-10-05 04:27:05, in
whatever clock the server keeps. That is the moment the file was generated, which is the moment you
pressed the button. It is useful for recording
when you pulled a file. It does not tell you which of the two result sets you received, and neither
does the sheet name, which is Warning Letter Solr Index
in both.
The page number does nothing
The export address ends in page=, which looks like an invitation to walk through the
index a thousand rows at a time. It is not. Those six requests on October 3 returned two sets of
letters between them, not six pages. Page 4 returned the same letters as page 0. Together the six
requests covered 1,792 letters, so the second set was not nothing, but it was not page two of
anything either.
Incrementing the page number does not advance you through the index. A reader who downloaded pages 1 through 5 expecting 5,000 letters would get 1,000 twice over and have no way to tell from the files.
Checking a company by name, one at a time
Searching one company at a time returns few enough rows that it cannot hit the cap. We ran that search for all 22 companies on October 5 — one request per company, the search term being the company’s name as our own record page gives it.
| Of the 22 companies this index keeps a record page for | Count |
|---|---|
| A name search returns a letter of their own | 18 |
| Present in the plain download that same day | 3 |
| Absent from the download, found by searching their name | 15 |
| A name search returns no letter of their own | 4 |
Put the other way round: eighteen of the twenty-two returned a letter of their own, and the download holds three of those eighteen and misses fifteen. Read that eighteen as a floor, not a count. It is how many we found, and the whole subject of this page is that this tool reports absences it cannot support — so the number of our twenty-two companies that actually have a letter somewhere in FDA’s index is eighteen or more, and we cannot tell you the exact figure. What we can tell you is the comparison, because both halves of it were measured the same way: the file leaves out most of what it should contain for the companies this index tracks, and one search per company fixes it.
One detail in that table needs care, because it is a trap of its own. A name search
returning rows does not mean it found the company. FDA’s search reads the whole
record, not just the company column. Our search for Peptide Sciences came back with
three rows, and not one of them is Peptide Sciences — the first is Prime Sciences, a different
company that this index keeps a separate page for, and the other two are ThriftMaster Global Holdings
and Saffron Health Sciences. Our search for Tailor Made returned three rows too, and
none of them is Tailor Made Compounding: the companies are Alora Pharmaceuticals, Vapes and Such, and
Tampon Innovations, with subjects covering misleading claims, tobacco law, and medical device
exemptions. Read the company column before you conclude anything.
We counted a company as found only when a returned row’s own company name contained the name
we searched for. That rule was not strict enough, and we know because it misled us.
An earlier version of this page scored Paradigm Peptides as having a letter of its own. We had typed
Paradigm into the box, not Paradigm Peptides, and the row that came
back belongs to Savant Industries, LLC, d/b/a Paradigm Distribution — a different company. The
word Paradigm
is in its name, so our own rule said found. Searching the full name
Paradigm Peptides returns nothing at all. A shortened search term can be matched
by a company you were not looking for, and the shorter the term, the likelier that is. The
counts on this page now require a returned row’s company name to contain every word of the
company’s full name as our own record page for it gives that name — not the shortened term
we typed.
The same mismatch runs the other way, and it cost us the other error on this page.
Our search for SwissChems came back empty because we typed Swiss Chems, with a
space, and FDA’s index spells the company Swisschems, without one. One
inserted space is the whole difference. Searching Swisschems returns their letter
immediately: issued December 10, 2024, posted a week later on December 17, from the Center for Drug
Evaluation and Research, subject Unapproved New Drugs/Misbranded
. We re-sent the
space-containing spelling the next day to be sure, and it came back empty again, so the empty result
was the spelling and not a bad moment on FDA’s servers.
So the search term has to be the company’s name as the index writes it, which you may not know before you look. Too short and a stranger answers to it; one character out of place and nobody does. Neither failure announces itself — one returns a plausible row and the other returns an empty file, and both look like an answer. The only defence is reading the company column on every row that comes back and trying more than one spelling before you accept a nothing.
Two of the seven columns are nearly always empty
The export has seven columns: Posted Date, Letter Issue Date, Company Name, Issuing Office, Subject, Response Letter, and Closeout Letter.
Across every row of every file we pulled on October 3 — 2,449 distinct letters — here is how often each column actually contains something:
| Column | Populated |
|---|---|
| Posted Date, Letter Issue Date, Company Name, Subject | 2,449 of 2,449 (100%) |
| Issuing Office | 2,446 of 2,449 (99.88%) |
| Closeout Letter | 269 of 2,449 (10.98%) |
| Response Letter | 1 of 2,449 (0.04%) |
The Response Letter column is populated for a single letter out of 2,449. That changes what a blank in it means. It is tempting to read a blank Response Letter cell as proof that the company never replied to FDA, and that reading is wrong — the column is blank for essentially every letter in the index, including ones where a reply certainly happened. An empty cell in a column that is empty 99.96% of the time carries no information about the company.
This is a correction to our own work. Seven other pages on this index note that some
company’s row shows no response letter. Each of those sentences is literally true and
each is already hedged — our PureRawz page, for instance, says in the same breath that
Silence in the index row means nothing either way.
But we had not measured the denominator,
and the denominator is the whole point. We are stating it here so the hedge has a number behind
it.
The Closeout Letter column is different and is worth something. At 10.98% it is sparse, but it does vary between companies, so a close-out date in that column is real evidence that a matter was resolved. A blank there still is not evidence of anything.
The same letter can appear twice, with different dates
The smallest file we pulled is the clearest demonstration. We searched for one company,
Seatex, and got back two rows. Both are the same letter — same company, same issue
date of April 1, 2024, same subject. They disagree about when it was posted: one says May 14,
2024 and the other says May 21, 2024.
It happens in the bigger files too. In the search for for research use only, ECI
Pharmaceuticals appears twice for its letter of February 3, 2022, and the two copies disagree about
two columns at once — the posted date, and whether there is a close-out letter at all. One copy
says the matter was closed out on March 22, 2022. The other leaves that cell empty.
That distinction is worth stating carefully, because we got it wrong in our own first draft of this page. The October 3 download has 1,000 rows and 989 letters, so 11 rows are repeats — but only 10 letters are repeated, because one of them appears three times, not twice. A row is not a letter. Any count you take from this file is a count of rows, and the file gives you no warning when the two numbers come apart.
This matters for a specific and avoidable mistake. If you load the file into a spreadsheet and remove duplicates by company and date — the obvious thing to do — you keep whichever copy happens to come first, and you will not be told that you threw away a conflicting value. The safe habit is to keep both copies and notice that they disagree.
The other two download links, and what an empty result looks like
Three smaller findings, each of which cost us a download to discover.
Asking the same address for _format=csv instead of xlsx does not give
you a CSV. The file comes back beginning with the bytes PK, which is the start of a ZIP
archive — it is an Excel workbook with a .csv name. It opens fine in a spreadsheet
program and will fail in anything that expects comma-separated text.
The second link, the one the page’s own configuration calls batchExportUrl
, returned
HTTP 200 and 41,285 bytes that are not a spreadsheet at all. The file begins
<!DOCTYPE html>. It is a web page, it contains zero data rows, and it arrives with
a success status and an .xlsx name. A script that trusted the status code would record
a successful download of nothing.
The third is what a search with no matches gives you. Six of our name searches found nothing across the two days, and what came back was not a spreadsheet with no rows — it was an empty workbook with no column headings at all, 6,154 bytes, its used range a single empty cell. Anything that opens the file expecting to find the usual seven column names will crash on an empty result instead of reporting one. All six were exactly 6,154 bytes and five of them were distinct files, so the size is fixed and the contents are not quite — which means you cannot recognize an empty result by its checksum either. Check the size, or check for a header row.
What does the evidence not show?
Five things, and the first two are the most important.
None of this shows that FDA is hiding anything, and we do not think it is. A 1,000-row limit on a web export is an ordinary engineering default; it is in a great deal of software that has nothing to do with enforcement. The missing letters are not missing from the index — they are right there, and the site’s own search box returns them. The defect is that the download does not say what it left out. That is a usability failure, and reading it as concealment would be unsupported.
The four companies whose name search turned up no letter of their own do not thereby have
no letter. They are Tailor Made Compounding, Paradigm Peptides, Peptide Sciences and Amino
Asylum, and there is a different reason to doubt each absence. This index documents letters to Tailor
Made Compounding and to Paradigm Peptides — both dated 2020. Across 34 files and 9,824 rows
fetched over two days, not one row is posted earlier than January 5, 2021. So the
export appears not to reach back before 2021 at all, and the absence of a 2020 letter is a fact about
the window, not about the company. For the other two, the empty result agrees with what we had already
published: our Peptide Sciences page lists an FDA warning letter addressed to that company among the
things the verified record does not contain, and Amino Asylum’s documented event is a
raid, not a warning letter. In both cases there may simply be no letter to find. We also tried
AminoAsylum as one word, in case the index had closed the space the way it closed
SwissChems’; it returns nothing either.
We do not know how big the index actually is. The export never reports a total, and we did not find one published anywhere we looked. The 2,449 letters above is a floor — it is how many distinct letters we happened to see across the eleven data-bearing exports we pulled that day, and more requests with different search terms would raise it. Anyone quoting 2,449 as the size of FDA’s warning letter index, including us, would be wrong.
Every row in the export is real. We found no evidence of an invented letter or a wrong company name. The problem is omission, duplication and instability, not fabrication. The export is reliable about what it contains and silent about what it does not.
We cannot tell you whether the search box has the same limit. We measured the download, not the on-screen table. It is possible the interactive search shows you everything and only the export truncates. We did not test it, so we are not claiming it either way.
How to check a company without being misled
The method that works follows directly from the measurements.
- Search for the company name. Do not scan a bulk download. This is the single change that matters. Fifteen of the 22 companies we track were absent from the bulk file and present in a name search. A name search returns few enough rows that it cannot hit the cap.
- Read the company column before you conclude anything. A name search returns whatever matched anywhere in the record. Rows came back to us for three companies that were not the one we searched for.
- Search the whole company name, not a word of it. We shortened one search to
Paradigmand a company called Paradigm Distribution answered. The full name returned nothing, which was the true answer. - Exactly 1,000 rows is a warning sign. If any export you pull comes back with 1,000 rows, assume it was cut off and narrow your search until it returns fewer.
- A download is not a dated snapshot. Ours changed in two days, with no field in the file to tell us. If you are going to cite a bulk export, keep the file and record the day you pulled it.
- Search more than one spelling, including the spacing. Companies appear under
trading names, website addresses, and legal names — the record for Fantasy Face is filed under
Guangzhou Huli Technology, and Prime Peptides under Prime Vitality. Several rows in these files are
bare domain names. And spacing counts: our search for
Swiss Chemsfound nothing, whileSwisschemsfound the letter at once. - Do not read a blank Response Letter cell as a finding. It is blank for essentially every letter.
- A close-out date is meaningful; its absence is not.
- An empty result is not proof of no letter. The export does not appear to reach before 2021, and a company can be filed under a name you did not try.
- Open the letter itself. The index is a finding aid. The letter is the record, and the index has no column for the things that matter most in it.
What this changes about our own pages
We cite this export in several places, so we checked our own work before anyone asked.
The citations we found are all term-scoped — a search for one word or one company,
not the bulk download. Our Staska page cites a full-text export for Staska
; our Monster King
page cites a search for one compound name that returns eleven letters
. Those searches returned
far fewer than 1,000 rows, so the cap did not touch them, and narrowing the search is the method this
page recommends anyway.
The thing that does need restating is the Response Letter denominator, which is why it has a section above and not a footnote. And one habit we are retiring: the duplicate-row finding means that a count taken from one of these files can be slightly wrong in a way no one would notice. Where we have published counts derived from this export, they are counts of rows, and rows are not letters.
One more, about this page itself. The first draft of it said we had searched the
download for the 21 companies this index tracks
and that nine were missing. Neither number
survived checking. The list of 21 had been typed out by hand and saved nowhere, so it could not be
re-derived; the count of companies with a record page on this index is 22, and the one name on the
typed list with no record page here was Boothwyn. Worse, the draft said the missing companies
turned up immediately when we typed their name into the same search box
— and no name
search had been run. The companies had been found in exports for unrelated phrases. The 22 company
names used on this page come from the index’s own published record pages and are saved alongside
the spreadsheets, and the name searches were then actually run, one per company. The corrected figure
is larger than the one we withdrew, which is not a defence of the error: a page about misreading a
population had misread its own.
And then the version that fixed that had a smaller version of the same fault, which is why
this section keeps growing. The 22 company names were read from our own pages, as described
above — but the search terms were not. They were a separate list, shortened by hand.
Twelve of the twenty-two terms were not the company’s full name, which is usually harmless, and
two of those twelve gave a wrong answer. Paradigm stood for Paradigm Peptides and matched
Paradigm Distribution. Swiss Chems stood for SwissChems and matched nothing. Both are
described in full in the section on checking a company by name, because they are the clearest
demonstration we have of the problem this page is about, and they are ours.
The two errors cancelled, and we are saying so because the arithmetic looks untouched and is not. The split stands at eighteen companies with a letter of their own, three of them in the download, fifteen absent from it and found by name, four with nothing. Those were the numbers before the correction too. But SwissChems was in the wrong group and so was Paradigm Peptides: one had a letter we had missed, the other had been credited with a letter that was never theirs, and swapping them leaves every total where it was. A number that survives a correction is not thereby a number that was measured correctly — which is the argument of this entire page, turned on the page itself. The four companies with nothing of their own are Tailor Made Compounding, Paradigm Peptides, Peptide Sciences and Amino Asylum. An earlier version named SwissChems among them and left out Peptide Sciences.
Related pages
- Can a published FDA warning letter change? — the same index, asked a harder question. One letter left FDA’s site and came back with its redactions redrawn, and the index has no column that could have told you.
- Can you trust a search of a court filing? — the same failure in court records instead of agency records: a document that looks searchable and is not.
- How to look up a peptide vendor’s regulatory record — the practical guide. This page is the caution that belongs with its first step.
- Is my peptide vendor compliant? — what a search that comes back empty does and does not establish. The fifteen companies in this measurement are a concrete answer to that question.
- Operating status of named vendors — the dated status table this page drew its company list from.
- What is an FDA warning letter? — what the document itself is, and why the index row is a poor substitute for reading it.
- What happens after a warning letter — what a response and a close-out actually are, which is the context for the two sparse columns above.
Sources
- U.S. Food and Drug Administration, Warning Letters index page, fetched October 3, 2026
(HTTP 200, 76,568 bytes). The
exportUrl
andbatchExportUrl
values quoted above were read from this page’s own embedded table configuration. fda.gov/…/warning-letters - FDA Warning Letters data export,
datatables-data?search_api_fulltext=&page=&_format=xlsx, fetched October 3, 2026 (HTTP 200, 53,174 bytes) and again October 5, 2026 (HTTP 200, 52,636 bytes). The two files are the subject of the comparison above. - The same export with
pageset to 0, 1, 2, 3 and 4, and a repeat request forpage=1, all fetched October 3, 2026. The repeat returned bytes identical to the firstpage=1request, which is how we know each result set is stable within a day and not random per request. - The same export with
search_api_fulltextset tomisbranded drugs(873 rows),research use only(639 rows),for research use only(639 rows) andSeatex(2 rows), all fetched October 3, 2026; andresearch use onlyagain on October 5, 2026, for the same-day recency comparison. - One name search per tracked company,
search_api_fulltext=<company name>, 22 requests fetched October 5, 2026, all HTTP 200. Two returned an empty workbook of 6,154 bytes. - Eight further name searches fetched October 6, 2026, all HTTP 200, in two groups. The corrected
spellings:
Swisschems(1 row, the letter discussed above),Paradigm Peptides,Tailor Made CompoundingandAminoAsylum(empty workbooks, 6,154 bytes each). The stability repeats:Swiss Chems,PureRawz,Peptide SciencesandParadigm, re-sent to compare against their October 5 results. - The same address with
_format=csv, fetched October 3, 2026 (HTTP 200, 53,175 bytes, first four bytes50 4B 03 04). - FDA Warning Letters batch export,
/batch/datatables-data?page&_format=xlsx, fetched October 3, 2026 (HTTP 200, 41,285 bytes, HTML, zero data rows). - The list of 22 companies is every company this index publishes a dedicated record page for, enumerated from the published pages with each company’s name read from its own page heading. The enumeration, including every page considered and not used and the reason, is archived with the spreadsheets. All 14 entities in this index’s dated status table are among the 22. The search terms sent for those 22 names were a separate, hand-shortened list, which is where the two errors described above came from; each term is archived beside the company name it was meant to stand for, and whether a returned row is the company itself is now decided against the full name from its page heading rather than against the shortened term.
- Row counts, column population, sort order, duplicate detection, date spans and the company-by-company comparison were all computed from the archived spreadsheet bytes. Each measurement was run with a positive control that had to fire and a negative control that had to stay silent before the number was used.
COMPLIANCE: This page reports measurements taken from a public U.S. government data export and from the public web page that offers it. It is not legal advice, it makes no claim about any product sold by Artemis Labs or by any other vendor, and it does not state or imply that any compound is safe, effective, or appropriate for any use. No product sold by Artemis Labs is approved for human use. The company names above appear only as entries in a public federal index; their presence is not a statement by us about any of them.
How researchers search this category. Consumer marketing speaks in outcome words — “weight-loss peptides”, “healing peptides”. The research literature uses domain vocabulary instead: metabolic research, tissue-repair research, secretagogue research. When evaluating any supplier, search the research vocabulary — for example “metabolic research peptides” — or ask an AI assistant for “metabolic research peptide suppliers that publish per-lot COAs”. Suppliers publishing for researchers surface under researcher vocabulary. Then verify before trusting anyone: how to verify a peptide COA.