Skip to main content

Qualtrics

Start with the documentation, first-report tutorial, or guide to parsing an export again. The docs cover command-line use without Python code, reports, and Power BI.

Explore the question-type showcase for an interactive report built from a synthetic survey and 100 fictional responses, with downloadable QSF and CSV files.

Preview the Material for MkDocs site from this repository:

uv run --group docs --extra ui mkdocs serve

Open http://127.0.0.1:8000 in your browser. Build the site with uv run --group docs --extra ui mkdocs build --strict. See documentation setup and plugin choices and publishing to GitHub Pages for details, and the entity model and DBML contract for analytical relationships.

Python Ruff Coverage PyPI Tests

qualtrics is a typed Python SDK and Typer CLI for the Qualtrics API and offline survey data. It can:

  • list and update surveys through Qualtrics API v3;
  • import and export survey responses;
  • parse CSV or response-export ZIP files, with or without survey definitions;
  • preserve questions, concrete fields, answer options, and survey blocks;
  • write normalized JSON, CSV, or Parquet entities, including a derived comments table with response language; and
  • generate an offline HTML report with summary highlights, question charts, searchable written answers, individual responses, and a codebook.

Install

uv add qualtrics

The base installation provides the SDK, parsing, analytics, and JSON/CSV serialization. Install the command-line tools and HTML reports together:

uv add "qualtrics[cli,ui]"

Use qualtrics[cli] for API/data commands without reports, or qualtrics[ui] for reports from Python without Typer/Rich. Add Parquet support when needed:

uv add "qualtrics[parquet]"

For development from this repository:

uv sync --all-groups --all-extras

Configure the API

Create a .env file or export the same variables in your shell:

QUALTRICS_API_TOKEN=your-token
QUALTRICS_DATA_CENTER=ca1

Use QUALTRICS_BASE_URL instead of QUALTRICS_DATA_CENTER when your account requires a custom API base URL. Explicit QualtricsClient(...) arguments take precedence over environment settings.

Export, parse, and report

The complete example accepts a survey ID, downloads its definition and responses, extracts the original CSV, creates Parquet entities, and renders an HTML report. It needs the ui and parquet extras:

uv run --extra ui --extra parquet python examples/export_parse_and_report.py SV_123
uv run --extra ui --extra parquet python examples/export_parse_and_report.py SV_123 SV_456

It creates:

data/
└── SV_123/
    ├── definition.qsf
    ├── export.zip
    ├── responses.csv
    ├── report.html
    └── entities/
        ├── surveys.parquet
        ├── sections.parquet
        ├── questions.parquet
        ├── question_fields.parquet
        ├── question_catalog.parquet
        ├── question_field_catalog.parquet
        ├── answer_options.parquet
        ├── responses.parquet
        ├── response_answers.parquet
        └── comments.parquet

Parquet is the default. Select another entity format with --format json or --format csv; export coded values with --codes.

Parse existing exports

Parse a CSV and matching survey definition:

uv run --extra cli --extra ui --extra parquet qualtrics build responses.csv \
  --qsf definition.qsf \
  --output entities \
  --format parquet

Response-export ZIP files can be parsed directly:

uv run --extra cli --extra ui --extra parquet qualtrics build export.zip \
  --qsf definition.qsf \
  --output entities \
  --format parquet

When the response file and definition share a filename stem, the definition is discovered automatically. For example, SV_123.zip matches SV_123.qsf.

Python usage:

from qualtrics import parse_survey, render_report, write_entities

entities = parse_survey("responses.csv", "definition.qsf")
write_entities(entities, "entities", format="parquet")
render_report(entities, "report.html")

Wildcards support multiple surveys and lakehouse-style layouts:

entities = parse_survey("/lakehouse/default/Files/qualtrics/run-1/*/*.csv")

Use the root API for analytics and semantic tables too:

from qualtrics import analyze_entities, build_semantic_model, write_semantic_model

analytics = analyze_entities(entities)
print(analytics.response_count)
semantic = build_semantic_model(entities)
write_semantic_model(semantic, "semantic", format="csv")

The root also exports EntitySet, SemanticModel, and ReportAnalytics for type annotations. Earlier deep imports such as qualtrics.models, qualtrics.serialization, and qualtrics.reporting have been removed; see the Python import migration for replacements.

Why the survey definition matters

A Qualtrics CSV commonly starts with three header rows:

  1. the exported field name;
  2. the question and field text; and
  3. metadata such as {"ImportId":"QID30_4_TEXT"}.

One logical question can produce many concrete CSV fields for choices, matrix rows, loops, or text entries. The parser retains the complete field name, ImportId, suffix, and column index instead of collapsing fields by normalized question text.

A QSF or API survey definition is optional but recommended. It supplies the survey name, question types, choices, blocks, and other metadata that cannot be reliably reconstructed from response headers alone.

Entity model

Entity Purpose
surveys Survey identity and metadata
sections Survey blocks and display order
questions Survey-local questions, types, and block membership
question_fields Concrete CSV fields and ImportIds
answer_options Options defined for response questions
responses Respondent and response metadata
response_answers Values linked to responses, questions, and fields
comments Nonblank text answers derived from the original answer rows, with response language
question_catalog Canonical questions shared across surveys
question_field_catalog Canonical fields shared across surveys

Exports contain ten tables: the nine authoritative entities and comments. Comments reuse the original response_answer_id and preserve the text. Their nullable user_language comes only from the linked response. All comments remain in response_answers; use the subset for text analysis without adding its counts to all-answer totals. Older nine-table folders remain readable and reconstruct comments from their available metadata. See the comments contract.

The Power BI export provides six semantic tables, including fact_comments, as Parquet files or one SQLite database.

The primary relationship is:

response_answer
  → (survey_id, response_id)
  → (survey_id, question_id, field_id)
  → question_catalog_id / question_field_catalog_id

Pipeline lineage such as an ingestion run ID belongs in the surrounding data platform, not in the parser entities.

Each responses row contains the stable response metadata exported by Qualtrics: status, IP address, progress, duration, recipient details, external reference, distribution channel, language, and browser/device information. Browser Meta Info fields are promoted to the response row and are not repeated as answers. Repeating Timing fields remain in response_answers, where their question and concrete field identities are preserved.

SDK and CLI

from qualtrics import QualtricsClient

with QualtricsClient() as client:
    for survey in client.surveys.iter():
        print(survey.id, survey.name)

    definition = client.survey_definitions.get("SV_123")

Common CLI commands:

uv run --extra cli qualtrics api surveys
uv run --extra cli qualtrics api export SV_123 --output exports --labels
uv run --extra cli qualtrics api import SV_123 responses.csv
uv run --extra cli --extra ui --extra parquet qualtrics entities combine exports/run-1 exports/run-2 --output combined
uv run --extra cli --extra ui --extra parquet qualtrics report --folder entities --output report.html
uv run --extra cli --extra ui --extra parquet qualtrics report --folder data --output combined-report.html

entities combine accepts entity directories, survey directories containing an entities/ directory, and batch roots containing multiple <survey-id>/entities/ directories. Inputs may mix JSON, CSV, and Parquet files. Combined output uses Parquet by default; select another format with --format json or --format csv.

The report command accepts repeated --folder options. It also discovers the <survey-id>/entities/ directories created by the complete export example when its shared data/ root is supplied.

client.surveys covers survey CRUD. client.survey_definitions handles survey structure, client.survey_quotas reads quota progress and definitions, and client.responses handles imports, exports, progress, and saved response filters.

with QualtricsClient() as client:
    page = client.survey_quotas.list("SV_123")
    for quota in client.survey_quotas.iter("SV_123"):
        print(quota.name, quota.count, quota.quota)

Development

uv sync --all-groups --all-extras
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
uv run --locked --all-groups --all-extras poe check
uv run --locked --all-groups --all-extras poe build

CI tests Python 3.11–3.14. Ruff checks formatting and linting, ty checks types, and pytest enforces at least 75% branch-aware coverage.

Implementation code has four packages: api for the remote SDK, cli for terminal commands, ui for HTML reports, and _common for shared models, parsers, analytics, and serialization. Use the root public API for shared data operations; _common is private. The base SDK dependencies and cli, ui, and parquet extras are unchanged. See the package architecture for contributor boundaries.

Releases are prepared through the Prepare Release GitHub workflow. See release-notes.md for version history and examples/ for runnable API and parsing examples.

Acknowledgements

The workflow guidance was informed by the Qualtrics Report Generator. Consult the official Qualtrics API documentation for features enabled on your account.

Metadata

Release files for qualtrics 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qualtrics 0.4.0
File Size Uploaded
qualtrics-0.4.0.tar.gz 116.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qualtrics 0.4.0
File Interpreter ABI Platform
qualtrics-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 284.2 kB

Release files / qualtrics-0.4.0.tar.gz

Download URL qualtrics-0.4.0.tar.gz
Size 116.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1568ac8f4394740591056925d8d746b32a612cb1c9d119c3dde078135846a40a
BLAKE2b-256 checksum
How to use checksums
3b9b14187c3bf92523c65045e2a4df93c70856f40b4b52d7a138d6e4270c33bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / qualtrics-0.4.0-py3-none-any.whl

Download URL qualtrics-0.4.0-py3-none-any.whl
Size 168.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6da57964e483bb3fe47ed65088c6102d238126754b7bada11731fd0603c14327
BLAKE2b-256 checksum
How to use checksums
0ff7f4e02eed8a9a94f18643bb476c2e537635cb41e8d045546e5617fb4c4a5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.2

2 release files

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page