Keep the small response as your working input
Begin with https://api.redditextract.com/v1/search?q=index&subreddit=PostgreSQL&limit=3. Send the request from your backend with the domain API key in a supported authentication header. The text query and community scope narrow this particular inspection; the request does not define a random or complete sample. limit=3 is an upper bound for the page, and an empty response is a valid possible outcome.
Save the returned response unchanged with the request parameters, your local retrieval time and the mapping version you intend to test. These are records of your own workflow, not additional API response fields. Keep credentials out of this fixture. The archive is independent and historical, not a live official Reddit interface, and it does not promise that repeating the request later will produce the same objects.
Write the source-to-output ledger
Make the mapping readable before you implement it. A local ledger can name the output column, the observed source property, its accepted type, the action for an absent value and whether the output is copied or derived. For example, content_source can be a local marker saying title or text; source_page can come from your request log. Neither name claims a new field in the API response.
Inspect each returned object rather than inferring its shape from one record. List the properties you actually see, their runtime types and whether they are absent or explicitly null in other objects. Three inspected records can uncover a failing assumption but cannot prove a field is always present. A successful empty page gives no observed record schema at all; keep it as an empty fixture.
Record why you chose title or text
q searches title and text. With several search terms, the terms must match together within a matching field; splitting them between title and text is not enough. For q=index, inspect those fields independently and decide which content to retain. If the body is absent, either keep that absence or use a documented title fallback with its source marker. Do not silently present the fallback as original body text.
Test absence before converting a value
Preserve identifiers as identifiers. If a text property is present, verify that it contains a string before applying your chosen whitespace normalization; retain the original text when auditability matters. An absent property, null and an empty string should remain distinguishable until you explicitly decide how your destination represents them. Do not silently convert a missing score into zero or cast an unexpected object to a textual value that looks valid.
Time conversion requires a verified representation and unit. If created_utc or another time property is present, inspect its value before choosing a conversion; do not divide a number by 1000 merely because your destination expects milliseconds or seconds. For an optional author or score, record a validation failure or a nullable value according to your own contract. Do not infer that every post and comment shares all those properties.
Account for every input record
Keep parent_id and link_id only if returned and useful to your task. They can support a local join, but neither a complete thread nor the presence of every referenced record is guaranteed. They are not exposed search filters. A field extraction job can deliberately leave relationship expansion out, retaining the reference and its unresolved status rather than manufacturing a parent object.
Use clearly labeled synthetic cases to test the choice itself: title only, text only, both present, explicit null and neither property present. Check both the projected value and its source marker. Keep an unchanged input object beside each rejected case and write a local reason. For a mapper that emits at most one row per record, accepted plus rejected records should account for the received records; never confuse these counts with a count of the whole archive.
Choose a reason to fetch another page
If you request another page, keep limit and the selection criteria in your request log. Results follow _doc archive order, not chronological, relevance or score order. min_score only filters. Retrieval is bounded by 100 records per request and 100 pages per query, and exact, lower-bound or unknown totals must not be turned into an exhaustive-coverage claim. A local sort changes only the records you collected.
Budget one credit for every successful page retrieval, including an empty page. A successful response followed by your own parsing failure remains billed; rerunning the mapper on the saved response makes no new request. The price is $1 per 1000 successful requests, with a $50 minimum paid top-up for 50000 credits and an optional conditional 100-credit trial. The account panel, not public /v1/status, is where you inspect the domain balance.