Skip to main content
v2026.11,772 entries · CC-BY 4.0

The REDCap API: Tokens, Exports, and Automating Data Pulls

A practical guide to the REDCap API: how project-scoped tokens are generated and what rights they inherit, the record/metadata/file export endpoints, and a worked example of an automated, scheduled data pull.

Written and maintained by CASRAI Editorial Board

Last updated

The REDCap API is not a single, site-wide service — it is scoped per project. Every REDCap project has its own API, reachable at the same base URL as the REDCap install itself, and every call to it is authenticated with a token tied to one project and one user’s rights within that project. That project-level scoping is the detail that trips up most first automation attempts: a token generated in one project has no access to any other, and a script written against one institution’s REDCap cannot simply be pointed at another’s without a new token and, usually, a new approval.

This guide covers how a project-level API token is generated and what it inherits from the requesting user, the shape of a REDCap API request, the three export content types that cover most automation needs — records, metadata, and files — and a worked example of pulling data on a schedule without hard-coding the token into the script itself.

What the REDCap API actually is

REDCap exposes a single HTTP endpoint per install (typically https://[your-redcap-host]/api/) that accepts POST requests. Every request identifies which project it’s acting on via the token, not a project ID in the URL — the token itself is the routing mechanism. There is no REDCap-wide API key; “the REDCap API” really means “this project’s API,” and a researcher with five projects who wants to automate all five needs five separate tokens.

The API sits alongside REDCap’s existing electronic data capture workflow rather than replacing it — records entered through the web form, a mobile app, or a survey response are all reachable the same way once they’re stored, and imports made via the API show up in the project exactly as if a user had typed them into a form.

Generating and scoping a token

A token is requested from inside the project, not from a REDCap admin console: the API module in the left-hand project menu has a “Request API Token” action. What happens next depends on the institution — some REDCap administrations auto-approve for users who already have sufficient rights on the project, others require a manual admin approval step, and some restrict token issuance to specific user roles entirely. There is no single institution-independent answer here; check the local REDCap administration’s policy before assuming a token will be available on request.

The token does not carry its own independent permission set. It inherits the rights of the user account it was generated under, as configured on that project’s User Rights page — including form-level and record-level restrictions, and critically the Data Export tool right, which has four settings: No Access, Full Data Set, De-Identified (strips fields tagged as identifiers), and Remove All Tagged Identifiers. A token generated under a user with de-identified export rights returns de-identified data through the API too — the API does not bypass whatever export restriction already applies to that user’s exports through the web interface.

Because of that inheritance, a token is a credential, not a scoped API key in the way a modern SaaS product issues one — anyone holding it can act with the full weight of the rights it inherited. Treat it accordingly: never commit it to a script, a notebook, or version control, and store it in an environment variable or a secrets manager the script reads at runtime instead.

Request format

Every REDCap API call is a POST with form-encoded parameters, never a query string with the token in the URL — this matters for logging hygiene, since URLs routinely end up in server access logs and browser history in a way POST bodies don’t. The parameters that appear on essentially every call:

  • token — the project-scoped token described above.
  • content — what you’re asking for: record, metadata, file, project, user, event, instrument, and several others.
  • formatjson, csv, xml, or (for some content types) odm.
  • returnFormat — the format REDCap should use for its own error messages, independent of the data format above.

Additional parameters layer on top depending on contentfields[] and forms[] to narrow a records export, events[] on a longitudinal project, rawOrLabel to choose between stored codes and their on-screen labels, and exportDataAccessGroups to include each record’s data access group in a multi-site project.

The three export shapes that cover most automation

Almost every automated pull is built from some combination of these three content values.

Records — the actual data

content=record returns the entered data itself, one row per record-event-instrument combination by default (REDCap’s own “long” format), or a wide, one-row-per-record layout if requested. Narrowing with fields[], forms[], and events[] is worth doing deliberately on any project with more than a handful of fields — pulling the entire record set on every scheduled run when a downstream script only reads three fields is unnecessary load on the REDCap server and a slower response for no benefit.

Metadata — the data dictionary

content=metadata returns the project’s data dictionary: every field’s variable name, form, field type, validation type, choice labels for categorical fields, and its branching logic expression if it has one. This is what makes a records export machine-interpretable rather than just a table of codes — a script that decodes a categorical field’s numeric values into labels, or that needs to know which fields are dates versus free text, should pull the metadata once (it changes only when the project design changes) and cache it, rather than re-fetching it on every records pull.

Files — uploaded documents

content=file is different in kind from the other two: it requires action=export, a specific record, field (which must be a File Upload field), and — on a longitudinal or repeating project — an event and possibly a repeat instance. The response is the raw file content itself with a Content-Type header describing it, not a JSON envelope, so file exports need to be handled as a separate branch in a pull script rather than parsed the same way as a records or metadata response. There is no single call that returns “every file in the project” — files are fetched one field-and-record at a time, which means a bulk file pull has to first enumerate which records have a populated File Upload field before requesting each one.

A worked example: an automated nightly pull

The pattern below — read the token from the environment, pull metadata once, pull records on a schedule, and write out a decoded CSV — generalises to most cron-style or Airflow-style automation, regardless of which HTTP client or wrapper library does the actual call.

Direct HTTP (Python, requests)

import os, requests

API_URL = 'https://redcap.example.edu/api/'
TOKEN = os.environ['REDCAP_API_TOKEN']  # never hard-code the token

def export_records(fields=None, forms=None):
    payload = {
        'token': TOKEN,
        'content': 'record',
        'format': 'json',
        'returnFormat': 'json',
        'rawOrLabel': 'label',
    }
    if fields:
        for i, f in enumerate(fields):
            payload[f'fields[{i}]'] = f
    if forms:
        for i, f in enumerate(forms):
            payload[f'forms[{i}]'] = f
    r = requests.post(API_URL, data=payload)
    r.raise_for_status()
    return r.json()

records = export_records(fields=['record_id', 'enrollment_date', 'consent_given'])

The same call with content: 'metadata' instead of content: 'record' (and no fields[]/forms[] restriction, since a data dictionary export doesn’t take those) returns the field definitions to decode against.

Wrapper libraries

Two maintained wrapper libraries exist specifically to avoid hand-rolling the request format above:

  • PyCap (Python) wraps the token/URL pair in a Project object and exposes export_records(), export_metadata(), and export_file() as methods, along with equivalents for events, instruments, users, and data access groups — handling the parameter formatting shown above internally.
  • REDCapR (R, on CRAN) provides an equivalent set — redcap_read(), redcap_metadata_read(), redcap_file_download() — built for the same project-token pattern, returning data frames instead of raw JSON.

Either wrapper is a reasonable default over hand-built requests for anything beyond a one-off script: they handle pagination-style batching on large exports, retry logic, and response-format quirks that are easy to get subtly wrong writing the raw HTTP calls yourself.

Keeping the token out of the script itself

Because a token inherits full export rights from the user it was issued to, a token committed into a shared repository, a notebook checked into version control, or a script emailed between colleagues is a credential leak with the same blast radius as sharing that user’s REDCap password. The practical pattern: store the token in an environment variable, a .env file excluded from version control, or an institutional secrets manager, and have the automation read it at runtime — never inline. If a token is ever exposed, it can be regenerated from the same API module that issued it, which immediately invalidates the old one; regenerating does not require deleting and recreating the project.

Worth deciding deliberately, not by default: whether the token should be generated under a dedicated service account with only the rights the automation needs, rather than under an individual researcher’s own account. A service-account token survives that person leaving the project or losing access, and its rights can be scoped narrowly (read-only export, specific forms) in a way that’s harder to guarantee when the token is just riding on one person’s full account rights.

Frequently asked questions

Does the REDCap API let me pull data from every project on an institution’s REDCap instance with one token?

No. A token is scoped to exactly one project. Automating pulls across multiple projects means requesting a separate token for each one and storing/rotating them independently.

Can the API create or modify the project’s form design, or only move data?

Both are possible in principle — REDCap’s API includes content=metadata import as well as export, which can alter the data dictionary — but most automation only needs the read/export side covered in this guide. Programmatic design changes carry more risk than data pulls and are worth a deliberately separate review before scripting.

Why does my exported records data show numeric codes instead of the labels I see on the form?

By default REDCap exports the underlying stored value for categorical fields, not the on-screen label — set rawOrLabel to label in the request if you want the human-readable text instead, or export the metadata alongside the records and decode them yourself against the field’s choice list.

Is there a REDCap-wide rate limit I need to design around?

There’s no single published number that applies everywhere — REDCap API throughput limits are configured at the institutional server level and vary by install. Check with the local REDCap administration before assuming a script that works against a small test project will scale unmodified to a production pull.

What’s the difference between the API and REDCap Mobile App offline sync?

They’re unrelated mechanisms. The Mobile App syncs a device’s offline-collected records back to the project over its own protocol; the API is a general-purpose HTTP interface any script or external system can call. A record entered via the Mobile App, once synced, is exportable through the API like any other record.

For the platform’s broader feature set, see the REDCap dictionary entry. For how REDCap compares to other survey and data-collection tools on cost and feature fit, see Qualtrics vs REDCap and the fuller survey tools comparison. For REDCap’s role in a regulated clinical trial specifically, see case report forms, 21 CFR Part 11, and clinical data management tools.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · included with Regulatory Radar

Ask about The REDCap API: Tokens, Exports, and Automating Data Pulls

Ask CASRAI answers research-administration questions and cites the passages behind every claim — and says so when the corpus does not cover something, instead of guessing. It comes with a Regulatory Radar subscription at $29 a month, alongside the daily digest of regulatory changes and the dashboard of what changed.

150 questions a day, on this site, over the API, or inside your own tools through the CASRAI MCP server.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Regulatory Radar

Stop finding out after the fact

$29/month, cancel anytime. Daily digest updates from our analysis, a dashboard holding the same items, and a cited assistant for everything they raise.

  • Federal Register, Federal Register+, Grants.gov, Regulations.gov, NSF News, UKRI, plus CASRAI’s own published content.
  • 72,264 indexed passages, and every answer cites the ones it drew on.