REST API Reference
Use these entry points to work with the Medialyst API.
1. Get An API Key
Create API keys from the Medialyst Developers page. The _ segment resolves to your current organization.
Give each key a clear name, choose the smallest useful scopes, copy the raw key immediately, and store it in secret storage or an environment variable such as MEDIALYST_API_KEY.
Send the key as a bearer token on API requests:
Authorization: Bearer <YOUR_API_KEY>Keep keys private
Medialyst only shows the raw API key once. Do not paste keys into prompts, commit them to source control, or share screenshots that reveal them.
2. Poll Journalist Moves
GET /api/v1/journalist-moves returns de-duplicated journalist outlet-move
records observed after an explicit timestamp or opaque cursor. It requires an
active Scale-plan credential and costs zero credits. since filters on when
Medialyst observed each move — not the move's effective date — so a poller
still receives late-reported moves. Each move also carries a nullable
published_at (the source's own publication time) for consumers that want
recently-announced rather than recently-observed moves.
Follow the Journalist Moves API guide for the response schema, the exclusive UTC cursor semantics, the de-duplication rule, the match-state default, and a complete daily polling example.
3. Automated Media Lists
Follow the Automated Media Lists guide to choose between an approval-gated browser deep link and a fully automated API job. The guide covers creating a researched journalist list, polling its background job, retrieving normalized results, and finding API-created lists in the Medialyst app.
target_list_size on POST /api/v1/media-lists:create-async is the most
credits the list may consume (1 to 1,000; the ceiling on paid plans), not a
row count. Each row that delivers a verified, deliverable email costs 1
credit; blank rows cost nothing and do not count against the budget. A
journalist with several matching articles appears once per article, and each
billable row costs a credit. The initial search is bounded by the target, then
the Beat Sweep keeps adding rows until the budget is spent or the angles run
dry, so result.total_rows can exceed target_list_size; the job's budget
object reports the cap, what has billed, and what rows still enriching hold.
Rule of thumb: ask for roughly twice the named journalists you want.
4. Enrich Journalists
POST /api/v1/journalists/enrich accepts known journalist references as well
as article URLs. The canonical reference request is:
{
"from": [
{
"type": "journalist_reference",
"name": "Jane Doe",
"publication": "The Daily Example"
}
]
}For every journalist_reference, name requires at least one of
publication, domain, or url. Use article_url with a real article URL
when you want to enrich that article's author; both source types can be mixed in
the same from array.
Enrichment is asynchronous. The create request returns a durable job id
immediately. Poll
GET /api/v1/journalist-enrichment-jobs/{jobId} until its status is complete
or failed. The deprecated create-call fields options.wait and
options.timeout_ms do not change this workflow.
This API uses outcome billing. It charges 1 credit for each source that returns a journalist with a verified, deliverable email and 0 credits for a source with no verified-email result. Misses are free — there is no upfront charge and no refund step.
5. Look Up Articles
GET /api/v1/articles/lookup returns canonical metadata — title, publish
date, author name and profile, site name, language, excerpt, and word count —
for one article URL. POST /api/v1/articles/lookup:batch does the same for
1-10 URLs. Add include=markdown to the single lookup when you need the
extracted body; it is the only accepted include value, and batch lookup does
not accept include at all. Author details are part of the default response.
Each successful URL costs 0.1 credit; per-URL failures cost 0 credits.
Follow the Article Lookup API guide for parameters, response shapes, error codes, and the lookup-specific rate limits.
6. Rate Limits
Limits are enforced per API key over a one-minute window unless noted. There is no daily request cap: credits, not requests, are the consumable, so a key can keep calling the API as long as it stays inside the per-minute and active-job limits below.
| Scope | Limit | Response when exceeded |
|---|---|---|
All /api/v1 routes | 60 requests per minute | 429 RATE_LIMITED, retry_after_seconds: 60 |
GET /api/v1/articles/lookup and POST /api/v1/articles/lookup:batch | 10 requests per minute (both routes counted together), plus 10 in-flight lookups per organization | 429 RATE_LIMITED, retry_after_seconds: 60 (per minute) or 1 (in flight) |
GET /api/v1/publications/lookup and POST /api/v1/publications/lookup:batch | 60 requests per minute; force_refresh lookups 5 per 15 minutes | 429 RATE_LIMITED, retry_after_seconds: 60 or 900 |
POST /api/v1/journalists/enrich | 10 active (pending or processing) jobs per key | 429 RATE_LIMITED, retry_after_seconds: 5 |
POST /api/v1/media-lists:create-async | 3 active (pending or processing) jobs per key; jobs complete on their own and deleting a list frees its slot | 429 RATE_LIMITED |
GET /api/v1/journalist-moves | 30 polls per minute | 429 RATE_LIMITED; see Journalist Moves errors |
Every 429 body has code: "RATE_LIMITED" and, where a wait is meaningful,
retry_after_seconds; the same value is sent as a Retry-After header.
Hosted MCP tools call these routes, so they share the same limits.
Handling 429
- Read
retry_after_secondsfrom the body (or theRetry-Afterheader), wait at least that long, then retry. Rejected requests still count toward the 60-per-minute window, so a tight retry loop only extends the wait. - Prefer batch routes for bursts: one
lookup:batchcall with 10 URLs is one request, while 10 single lookups use the whole article-lookup allowance. - For journalist enrichment and async media lists, a
429means the active-job cap, not request rate. Poll the existing jobs until they arecompleteorfailedbefore submitting more. - If an agent reports a "daily limit" on API calls, it has misread one of the
limits above — the REST API has no daily limit. Wait
retry_after_secondsand continue. The in-app chat does have a separate daily message cap; see the FAQ.
7. API Documentation
Browse the interactive API documentation at /api/docs.
8. Agent-Readable OpenAPI Reference
Use the raw OpenAPI document at /api/open-api.