Quick start
Download the current snapshot
- Register or sign in, create a machine credential, and store it in a secret manager.
- Send it as
Authorization: Bearer $MFC_PARTNER_API_KEYwhen fetching/v1/current.jsonand the manifest. - Fetch its
manifest_urland locateupcoming-films.ndjson.gz. - Request the payload with the same header, follow its one-minute signed R2 redirect without forwarding the API key, verify the SHA-256 checksum, and parse one JSON object per line.
export MFC_PARTNER_API_KEY='store-this-outside-your-code'
curl --fail \
-H "Authorization: Bearer $MFC_PARTNER_API_KEY" \
https://data.madridfilmcalendar.com/v1/current.json
# Use the same header for the manifest and payload gateway URL.
# Standard clients strip Authorization when redirected to the R2 host.
Coding agents
Using the API with a coding agent
If an agent is writing the integration, give it the contract and the task together. The prompt below contains the minimum context it needs to start without guessing the dataset shape.
Use the Madrid Film Calendar Bulk API v1.
Read the natural-language field guide before writing code:
https://data.madridfilmcalendar.com/docs#fields
Then use this public contract for structure and validation:
https://data.madridfilmcalendar.com/v1/openapi.json
https://data.madridfilmcalendar.com/v1/schemas/upcoming-film.schema.json
Start at https://data.madridfilmcalendar.com/v1/current.json, follow
manifest_url, and download upcoming-films.ndjson.gz.
Authenticate every data.madridfilmcalendar.com snapshot request with
Authorization: Bearer $MFC_PARTNER_API_KEY. Never put the key in a URL, log,
browser bundle, repository, prompt, or analytics event. The payload endpoint
redirects to R2; do not forward Authorization to the signed R2 URL.
There is one dataset; do not look for separate film or screening downloads.
Each NDJSON line is one upcoming-film record containing:
- film: the film and its Madrid Film Calendar research
- screenings: a non-empty array of current or future Madrid sessions
Verify the manifest and file SHA-256 checksums. Interpret showtime_local in
Europe/Madrid. Treat missing or nullable values as unknown, not false. Use
film_url and screening_url as the public links; do not invent direct cinema
ticket URLs.
My task is: [describe what you want to build]
The field guide explains what fields mean. OpenAPI and JSON Schema define their structure and validation rules. An integration should use both.
Feedback
What are you building?
The Partner API is new, and real integrations will shape what we document and improve next. If you are building an app, research project, visualization, or cultural tool, tell us what you are making, which fields you use, and where the contract gets in your way.
Dataset
Upcoming films
One film per line
Each record contains one film with at least one current or future Madrid screening. The screenings array includes venues, showtimes, first-party Madrid Film Calendar links, and public event annotations.
Field reference
Data dictionary
Each NDJSON line is an upcoming-film record. Arrays are written as []. Nullable fields may be null when the value is unknown.
Record and film identity
| Field | Type | Meaning |
|---|---|---|
| film | object · required | The rights-cleared film record associated with the screenings on this line. |
| screenings | array · required | One or more current or future Madrid sessions for this film. An exported record never has an empty array. See screening fields and event annotations. |
| film.id | integer · required | The stable, canonical FDB film identifier. Use it as the film key across snapshots. |
| film.film_url | URL · required | The canonical Madrid Film Calendar film page, with static partner-API attribution parameters. See first-party link rules. |
| film.title | object · required | Original and localized titles for the film. |
| film.title.original | string · required | The film's title in its original release language. |
| film.title.es | string · nullable | The published Spanish title, when known. |
| film.title.en | string · nullable | The published English title, when known. |
| film.year | integer · nullable | The film's release or production year. |
| film.runtime_minutes | integer · nullable | The canonical running time in minutes; a particular restoration or cut can differ. |
| film.film_type | string · nullable | The work format, such as feature, short, documentary, or episode. |
| film.original_language | string · nullable | The principal original language recorded for the film. |
| film.premiere_date | date · nullable | The earliest known premiere date in YYYY-MM-DD form. |
| film.status | string · nullable | The production or release status when it is known. |
| film.color | string · nullable | The recorded image presentation, such as color, black-and-white, or mixed. |
| film.silent | boolean · nullable | Whether the work is a silent film. Null means not established, not false. |
| film.wikidata_url | URL · nullable | A Wikidata entity URL used for external identity alignment. |
| film.research | object · optional | Madrid Film Calendar's cited editorial and structured research. Its child arrays may be empty. See attributes, credits and origins, versions and releases, editorial context, and film relationships. |
Screenings and event annotations
| Field | Type | Meaning |
|---|---|---|
| screenings[].id | integer · required | The stable FDB screening/session identifier. |
| screenings[].film_id | integer · required | The parent film ID. It always equals film.id in the same record. |
| screenings[].theater | object · required | The venue hosting the session. |
| screenings[].theater.id | string · required | The stable Madrid Film Calendar identifier for the venue. |
| screenings[].theater.name | string · required | The public venue name. |
| screenings[].showtime_local | local datetime · required | The Madrid-local start time, without a UTC offset, in YYYY-MM-DDTHH:MM:SS form. |
| screenings[].timezone | constant · required | Always Europe/Madrid. Combine it with showtime_local when converting time zones. |
| screenings[].version | vose · dubbed · null | vose means original or otherwise undubbed audio, including Spanish-language originals; it does not guarantee that subtitles are present. dubbed means audio dubbed into Spanish. null means the source genuinely does not specify the presentation, so consumers must not guess. Determine a film's original language or Spanish identity from film.original_language and its research fields, not from this screening value. |
| screenings[].free | boolean · required | Whether the session is advertised as free entry. |
| screenings[].screening_url | URL · required | A first-party link that opens the film page with this exact session selected and preserves partner attribution. See first-party link rules. |
| screenings[].annotations | array · optional | Public session-level context such as a presentation, discussion, guest, premiere, or special access note. |
| annotations[].tag | string · required | A stable machine-readable annotation category. |
| annotations[].label_es | string · optional | A short Spanish display label. |
| annotations[].label_en | string · optional | A short English display label. |
| annotations[].detail_es | string · optional | Longer Spanish context for the special session. |
| annotations[].detail_en | string · optional | Longer English context for the special session. |
| annotations[].guests | array · optional | Publicly announced people associated with the session. |
| guests[].name | string · required | The guest's public name. |
| guests[].role | string · optional | The guest's role in the film or event. |
| guests[].note_es | string · optional | Additional Spanish context about the guest's participation. |
| guests[].note_en | string · optional | Additional English context about the guest's participation. |
Editorial attributes
| Field | Type | Meaning |
|---|---|---|
| research.attributes | object · required | A dictionary keyed by stable attribute slug. Only researched attributes are present; an absent key does not mean false. |
| attributes.{slug}.category | string · required | The broader editorial category used to group the attribute. |
| attributes.{slug}.label.en | string · required | The human-readable English attribute name. |
| attributes.{slug}.label.es | string · required | The human-readable Spanish attribute name. |
| attributes.{slug}.value | JSON value · required | The assessed value. Its type depends on the attribute and can be boolean, numeric, text, structured JSON, or null. |
| attributes.{slug}.evidence | string · nullable | Madrid Film Calendar's concise explanation of why the value applies. |
| attributes.{slug}.sources | URL array · required | The evidence URLs supporting the assessment. These links do not license third-party page content. |
Genres, origins, credits and companies
| Field | Type | Meaning |
|---|---|---|
| research.genres[] | array | Genre assignments for the film. |
| genres[].slug | string | The stable machine-readable genre identifier. |
| genres[].name_en / name_es | string | English and, when available, Spanish display names. |
| genres[].is_primary | boolean | Whether this is treated as a principal rather than secondary genre. |
| research.countries[] | array | Countries associated with the film. |
| countries[].country | string | The country name or code recorded by FDB. |
| countries[].role | string | How the country relates to the film, such as production or co-production. |
| research.languages[] | array | Languages associated with the film. |
| languages[].language | string | The language name or code. |
| languages[].role | string | How the language is used, such as original, spoken, or intertitle. |
| research.credits[] | array | People credited on the film. |
| credits[].name | string | The credited person's public name. |
| credits[].department | string | The broad credit department, such as directing, cast, or cinematography. |
| credits[].role | string · nullable | The specific credited role. |
| credits[].character | string · nullable | The performed character name for cast credits. |
| credits[].order | integer · nullable | The source ordering within comparable credits. |
| credits[].uncredited | boolean | Whether the contribution was not listed in the original on-screen credits. |
| credits[].wikidata_url | URL · nullable | A Wikidata identity link for the person. |
| research.companies[] | array | Companies associated with production, distribution, restoration, or another role. |
| companies[].name | string | The company name. |
| companies[].kind / role | string | The company type and its specific relationship to the film. |
| companies[].country / territory | string · nullable | The company's home country and the territory where this role applies. |
| companies[].wikidata_url | URL · nullable | A Wikidata identity link for the company. |
Source works, certifications, versions and releases
| Field | Type | Meaning |
|---|---|---|
| research.source_works[] | array | Works adapted or otherwise used as source material. |
| source_works[].kind | string | The source form, such as novel, play, article, or earlier film. |
| source_works[].title / author | string · nullable | The source title and credited author or creator. |
| source_works[].wikidata_url | URL · nullable | A Wikidata identity link for the source work. |
| research.certifications[] | array | Age or content classifications issued in a territory. |
| certifications[].system | string | The classification authority or rating system. |
| certifications[].territory | string · nullable | The country or market where the rating applies. |
| certifications[].rating | string | The issued classification. |
| certifications[].detail | string · nullable | Additional rating notes or reasons. |
| research.market_stats[] | array | Measured market facts such as admissions or box office. |
| market_stats[].territory | string · nullable | The market covered by the measurement. |
| market_stats[].metric / value | string / number | The measurement name and numeric value. |
| market_stats[].as_of / period | date / string · nullable | The observation date and reporting period. |
| research.versions[] | array | Distinct cuts, restorations, or presentation versions. |
| versions[].label / kind | string | The public version label and its version category. |
| versions[].runtime_minutes / year | integer · nullable | The version-specific runtime and creation or release year. |
| versions[].restored_by | string · nullable | The organization or people responsible for a restoration. |
| versions[].restoration_resolution | string · nullable | The advertised restoration resolution, such as 4K. |
| versions[].source_elements | string · nullable | The film or digital elements used to create the version. |
| versions[].aspect_ratio / sound_mix | string · nullable | The version's image ratio and audio presentation. |
| versions[].formats | string array | Known physical or digital presentation formats. |
| versions[].notes | string · nullable | Additional version or restoration context. |
| research.releases[] | array | Territory-specific premieres and releases. |
| releases[].territory | string · nullable | The market where the event occurred. |
| releases[].date | date · nullable | The release or premiere date. |
| releases[].kind | string | The release kind, such as theatrical, festival, or restoration. |
| releases[].distributor / note | string · nullable | The distributor and any contextual release note. |
Places, tags, festivals and editorial context
| Field | Type | Meaning |
|---|---|---|
| research.settings[] | array | Places and time periods represented in the story. |
| settings[].period_start / period_end | integer · nullable | The approximate first and last years of the setting. |
| settings[].place_name / country | string · nullable | The named setting and its country. |
| settings[].fictional / is_primary | boolean | Whether the place is fictional and whether it is a principal setting. |
| research.filming_locations[] | array | Real-world production locations. |
| filming_locations[].place_name | string | The specific location name. |
| filming_locations[].city / region / country | string · nullable | The location's geographic hierarchy. |
| filming_locations[].latitude / longitude | number · nullable | Coordinates when reliable public evidence is available. |
| filming_locations[].note | string · nullable | Additional context about what was filmed there. |
| research.tags[] | array | Curatorial, thematic, formal, and audience-facing tags. |
| tags[].slug | string | The stable machine-readable tag identifier. |
| tags[].name_en / name_es | string | English and Spanish display names. |
| tags[].kind | string | The tag family or vocabulary. |
| tags[].weight | number · nullable | Relative relevance when the source supplies a weight. |
| research.festival_entries[] | array | Festival selections, premieres, nominations, and awards. |
| festival_entries[].festival / festival_slug | string | The festival display name and stable identifier. |
| festival_entries[].edition_year | integer | The festival edition year. |
| festival_entries[].section | string · nullable | The programmed section or competition. |
| festival_entries[].premiere_kind | string · nullable | The premiere status advertised by the festival. |
| festival_entries[].award / award_result / recipient | string · nullable | The award, outcome, and named recipient when applicable. |
| research.endorsements[] | array | Public recommendations or endorsements by people or institutions. |
| endorsements[].name / kind | string | The endorser and whether it is a person, publication, institution, or other type. |
| endorsements[].context | string | What was said or the list/program in which the endorsement appeared. |
| endorsements[].source_url | URL · nullable | The public source for the endorsement. |
| research.trivia[] | array | Cited, editorially reviewed facts about the film. |
| trivia[].text_es / text_en | string | Spanish and English versions of the fact. |
| trivia[].category | string | The trivia topic or editorial category. |
| trivia[].spoiler_safe | boolean | Whether the text can be shown without revealing plot-sensitive information. |
| trivia[].source_url | URL · nullable | The public evidence source. |
Identity, comparisons and film relationships
| Field | Type | Meaning |
|---|---|---|
| research.geographic_identities[] | array | Evidence-based national or world-region identities associated with the film. |
| geographic_identities[].country / country_code / world_region | string · nullable | The normalized country, code, and broader region. |
| geographic_identities[].identity_type | string | How the identity applies, such as production, cultural, authorial, or narrative. |
| geographic_identities[].is_primary | boolean | Whether it is a principal geographic identity. |
| geographic_identities[].strength | number · nullable | The editorial confidence or relevance score. |
| geographic_identities[].evidence / source_url | string / URL · nullable | The reasoning and its public evidence source. |
| research.regional_identities[] | array | Subnational or local identities associated with the film. |
| regional_identities[].region / region_code / locality | string | The region, optional normalized code, and optional locality. |
| regional_identities[].identity_type | string | How the regional identity applies. |
| regional_identities[].is_primary / strength | boolean / number | Whether it is primary and its optional editorial strength. |
| regional_identities[].evidence / source_url | string / URL · nullable | The reasoning and its public evidence source. |
| research.comparables[] | array | Direct recommendations selected by an AI research agent while researching this film. These are explicit recommendations, not algorithmic similarity results. |
| comparables[].title / year | string / integer | The comparable film's title and optional year. |
| comparables[].rationale | string | Why the two films are meaningfully comparable. |
| comparables[].film_id | integer · nullable | The FDB film ID when the resolved recommendation is present in this snapshot. |
| comparables[].tmdb_id | integer · nullable | The resolved film's TMDB identifier when known. |
| research.relations[] | array | Explicit structural relationships to another FDB film. |
| relations[].film_id | integer · nullable | The related FDB film when it is present in this snapshot. |
| relations[].tmdb_id | integer · nullable | The related film's TMDB lookup identifier when known. Every relation has at least one of film_id or tmdb_id. |
| relations[].relation | string | The relationship type, such as remake or sequel. |
| research.series[] | array | Named franchises, cycles, or series containing the film. |
| series[].name / slug | string | The series display name and stable identifier. |
| series[].position | integer · nullable | The film's known order within the series. |
| series[].wikidata_url | URL · nullable | A Wikidata identity link for the series. |
| research.similarity_neighbours[] | array · maximum 10 | Up to ten films calculated by Madrid Film Calendar's internal semantic-similarity algorithm. No AI agent explicitly selected each pair; inclusion is not an editorial endorsement. |
| similarity_neighbours[].film_id | integer · nullable | The similar FDB film when it is present in this snapshot. |
| similarity_neighbours[].tmdb_id | integer · nullable | The similar film's TMDB lookup identifier when known. Every neighbour has at least one of film_id or tmdb_id. |
| similarity_neighbours[].rank | integer · 1–10 | Rank within the eligible neighbours published for this film. |
| similarity_neighbours[].similarity | number · −1–1 | An internal relative semantic-similarity signal, not a probability or quality score. |
Current pointer and manifest
| Field | Type | Meaning |
|---|---|---|
| current.api_version | constant | Always v1 for this contract. |
| current.snapshot_version | string | The immutable release identifier consumers should store to detect changes. |
| current.published_at | UTC datetime | When this snapshot became the current public version. |
| current.manifest_url | URL | The immutable manifest describing the current snapshot. |
| current.manifest_sha256 | SHA-256 | The lowercase hexadecimal checksum for verifying the manifest bytes. |
| manifest.api_version | constant | The manifest contract version. |
| manifest.snapshot_version | string | The immutable version described by this manifest. |
| manifest.generated_at | UTC datetime | When the snapshot data was generated. |
| manifest.datasets.upcoming_films | object | Counts and ID bounds for the upcoming-films dataset. |
| datasets.upcoming_films.record_count | integer | The number of NDJSON records and therefore upcoming films. |
| datasets.upcoming_films.screening_count | integer | The total nested screening count across every record. |
| datasets.upcoming_films.first_id / last_id | integer · nullable | The first and last film IDs in canonical record order. |
| manifest.license | object | Machine-readable license, attribution, scope, and exclusions. |
| manifest.license.identifier | string | The dataset license identifier. |
| manifest.license.url | URL | The canonical license text. |
| manifest.license.attribution | string | The exact attribution text consumers should reproduce. |
| manifest.license.scope | string | What Madrid Film Calendar rights the license covers. |
| manifest.license.excluded | string array | Content explicitly outside the snapshot license. |
| manifest.files[] | array | The plain NDJSON and gzip representations of this dataset, with verification metadata. |
| manifest.files[].path | string | The snapshot-relative filename. |
| manifest.files[].format | constant | Always ndjson. |
| manifest.files[].content_type | enum | Either application/x-ndjson or application/gzip. |
| manifest.files[].compression | enum | Either none or gzip. |
| manifest.files[].bytes | integer | The exact object size in bytes. |
| manifest.files[].sha256 | SHA-256 | The checksum consumers should verify before decompressing or parsing. |
Examples
Code examples
import gzip, hashlib, json, os, requests
base = "https://data.madridfilmcalendar.com"
auth = {"Authorization": f"Bearer {os.environ['MFC_PARTNER_API_KEY']}"}
current = requests.get(
f"{base}/v1/current.json", headers=auth
).json()
manifest = requests.get(
current["manifest_url"], headers=auth
).json()
file = next(
x for x in manifest["files"]
if x["path"] == "upcoming-films.ndjson.gz"
)
url = current["manifest_url"].replace(
"manifest.json", file["path"]
)
redirect = requests.get(
url, headers=auth, allow_redirects=False
)
redirect.raise_for_status()
# Deliberately omit Authorization on the cross-host signed request.
payload = requests.get(redirect.headers["Location"]).content
assert hashlib.sha256(payload).hexdigest() == file["sha256"]
for line in gzip.decompress(payload).decode("utf-8").splitlines():
record = json.loads(line)
film = record["film"]
print(
film["id"],
film["title"]["original"],
len(record["screenings"]),
)
import { gunzipSync } from "node:zlib";
const base =
"https://data.madridfilmcalendar.com";
const auth = {
Authorization:
`Bearer ${process.env.MFC_PARTNER_API_KEY}`
};
const current = await fetch(
`${base}/v1/current.json`, { headers: auth }
).then(r => r.json());
const manifest = await fetch(
current.manifest_url, { headers: auth }
).then(r => r.json());
const file = manifest.files.find(
x => x.path === "upcoming-films.ndjson.gz"
);
const url = current.manifest_url.replace(
"manifest.json", file.path
);
const redirect = await fetch(url, {
headers: auth, redirect: "manual"
});
// Deliberately omit Authorization on the R2 request.
const compressed = Buffer.from(await fetch(
redirect.headers.get("location")
).then(r => r.arrayBuffer()));
const upcomingFilms = gunzipSync(compressed)
.toString("utf8")
.trim()
.split("\n")
.map(JSON.parse);
API contract
Contract rules
- First-party links
film_urlopens the film page.screening_urlopens that page with the exact session modal, where the genuine cinema ticket/info action is shown. Static UTM parameters identify partner API referrals.- Immutable versions
- Published snapshot files never change. Corrections create a new version.
- Breaking changes
- Fields may be added compatibly within v1. Removing or changing meaning requires v2.
Snapshots
Versioning and updates
Store the last snapshot_version you processed. If it has not changed, there is nothing to download. When a film or screening is corrected, a new immutable version is published and current.json moves to it.
Compare the dataset's SHA-256 value in the manifest with the previous version to avoid processing unchanged content.
Terms
License and corrections
The snapshot dataset is licensed under Creative Commons Attribution 4.0. You may copy, modify, redistribute and use it commercially. When sharing the data or a substantial part of it, include the attribution from the active manifest and indicate your changes.
Attribution: Madrid Film Calendar FDB — https://data.madridfilmcalendar.com — licensed under CC BY 4.0. Snapshot: {snapshot_version}.
The license applies to Madrid Film Calendar's rights in the exported snapshot compilation, original research summaries and records. Citation links identify third-party evidence; they do not license those pages or their content. Madrid Film Calendar names, logos and trademarks are not licensed. Posters, licensed synopsis text, third-party ratings and other separately licensed material are excluded from this API. The manifest repeats this scope in machine-readable form.
The data is provided as-is, without warranty or endorsement by listed cinemas. To report an error, rights concern or removal request, email madridfilmcalendar@gmail.com; accepted corrections are published as a new immutable snapshot.
For machine-readable details, use the OpenAPI document and the published upcoming-film record schema.