How to export your data from OpsLevel before your contract ends
If your OpsLevel renewal is coming up, or you plan to move the catalog to a self-hosted Backstage portal, you can pull much of your data out yourself. Services, teams and checks can be extracted through the MIT-licensed OpsLevel CLI, which includes an opslevel export terraform command and returns list and get results as JSON or CSV, and through the GraphQL API. The result is a set of extracts, not a full-fidelity backup: it gives you the catalog content you can read and reuse, but it does not guarantee a copy of every setting, history or integration behind it. This section explains what to expect, and the rest of the page covers formats, API limits, gaps, sequence and contract planning.
Start by inventorying what you actually depend on. Services, teams, ownership and the attributes you filter on are the core of the catalog and are the easiest to extract. Scorecard results, check history, integration configuration, custom actions, user and role assignments, and audit records are the areas where you should expect gaps, and you should confirm with OpsLevel exactly which of these the CLI and API return in your account before you rely on them. Ask OpsLevel in writing what it will provide at contract end, in what format, and within what window, because the vendor's offboarding terms govern what you are entitled to, not this tooling. Also check the self-hosted edition documentation at OpsLevel self-hosted docs if your instance runs inside your network, since the extract path differs.
What you can export from OpsLevel and how
This table maps each OpsLevel data type to the export route that reaches it, the output format and the limits that shape a bulk pull. Use it to plan which path covers each input your Backstage catalog needs. The main takeaway is that the Terraform export, the CLI list and get commands and the GraphQL API cover different slices, so most migrations combine them.
| Data type | Export route | Output format | What to confirm or limit |
|---|---|---|---|
| Services | CLI list and get commands, GraphQL service queries | JSON or CSV for list and get results | Confirm which service fields and relationships the current schema returns |
| Teams and ownership | Terraform export, GraphQL team and ownership queries | Terraform for the export command, JSON from the API | Confirm how team-to-service ownership is represented in each route |
| Checks and rubric results | GraphQL queries and CLI list output | JSON or CSV for list and get results | Confirm whether rubric results are exposed per service in your version |
| Other catalog entities (domains, systems, APIs, tags) | Terraform export and GraphQL queries | Terraform or JSON | Confirm entity types and relationships against the current CLI and API schema |
| Large result sets | GraphQL with cursor pagination | Paged JSON responses | Each query returns at most 100 results, so plan one loop per entity type |
| Bulk request volume | Scripted CLI or API calls | Depends on route | Limits are 10,000 requests per 5 minutes per IP address and 400 requests per minute per API token |
| Licensing of the export tooling | Opslevel CLI on GitHub | Not applicable | The CLI is MIT-licensed, and the GraphQL endpoint is api.opslevel.com/graphql |
How the CLI and GraphQL API differ for a catalog export
Choose the export path by what you need from the data. The `opslevel export terraform` command produces structured definitions that describe how your OpsLevel configuration is built, which is useful when you want to reproduce services, teams or checks as code or review them in version control. The CLI's list and get commands produce flat records in JSON or CSV, which are easier to map field by field onto the metadata, spec and owner keys of a catalog-info.yaml file. Most catalog migrations need both: Terraform output for configuration you want to keep as code, and flat exports for ownership and service attributes you will feed into Backstage descriptors. Before you commit to either, run each command against a single team or a small service set and confirm the fields you need appear in the output, since the exact columns depend on your OpsLevel version and the CLI release you install from the OpsLevel CLI repository.
The GraphQL API at ` returns at most 100 results per query and uses cursor pagination, so a full export is a loop: request a page, read the cursor from the response, then request the next page until no further pages remain. Write the loop so that each run stores the last cursor and can resume after a failure, because a long export that stops midway is the most common source of an incomplete catalog. Keep your script's logic in one place so that the same page handling serves services, teams and checks.
Rate limits set the run time for large catalogs more than query complexity does. The API documentation describes a limit of 10,000 requests every 5 minutes per IP address and 400 requests per minute per API token. Divide your expected page count by the per-minute token limit to estimate the minimum duration, then add retries for throttled responses. Run exports under a dedicated service token so that other automation does not consume its budget, and confirm the current limits in the OpsLevel GraphQL documentation before planning a cutover window.
What does not export cleanly and the workarounds
The CLI and GraphQL API move services, teams and checks out of OpsLevel, but several kinds of operational history and configuration sit outside that path. Each card below names one gap, the workaround that usually closes it, and what to confirm with OpsLevel before you terminate a subscription or switch off the instance.
Historical check results and trends
Current check status can be read through the API, but the time series behind trend charts and maturity progress is not a documented export target in the sources reviewed for this page. Before you cut over, take a dated snapshot of pass and fail results per service and store it alongside the exported catalog, so you can show progress after the switch. In Backstage, Tech Insights only accumulates results from the point you enable it, so earlier history will not appear there on its own. Ask OpsLevel support whether historical check data can be exported in bulk and in what format.
Audit and activity history
Records of who edited an owner, changed a rubric or ran an integration are usually kept for an audit trail rather than as catalog data, and they are the first thing a compliance reviewer asks for. Confirm with OpsLevel what activity records exist, how far back they go, and whether they can be exported or only viewed in the product. If they cannot be exported, record the retention window and request a written export or copy before the subscription ends, and keep it in your own evidence store under the same retention rules you apply to other audit logs.
Integrations and webhook configuration
Source connections, webhooks and push-based integrations are configured in the OpsLevel interface and are not part of the catalog data model. Document each one before you switch: the source system, the event types, the target endpoint and the owner who approved it. In Backstage, the equivalent connections are rebuilt with catalog providers, discovery locations and plugins, and their credentials must be issued again in your own secrets store rather than copied. Treat any webhook secret as compromised once the old instance is retired, and rotate it.
User accounts and SSO settings
Users, roles and SSO configuration in OpsLevel do not map one to one onto Backstage identities. Export the user list from the API as a reference, but do not treat it as an authentication source. In Backstage, sign-in resolvers must map each provider to the same identity, and guest access should not be left on in production. Plan the identity mapping against your own identity provider, confirm the role assignments with the OpsLevel account team, and remove the old SSO application only after users have signed in to the new portal.
Custom rubric logic with no direct equivalent
Some OpsLevel rubric conditions combine filters, levels and ownership rules in ways that do not translate line by line into Backstage Tech Insights checks. Inventory every custom rule, record its intent in plain language, and mark which ones have a facts-based or rule-based equivalent and which need a custom plugin or a manual process. Expect some rules to be simplified or dropped during translation, and get sign-off from the team leads who rely on the scores before you retire the original rubric.
Rendered dashboards and reports
Dashboards and rendered reports are generated views over the data, so exporting the underlying services and checks does not reproduce them. Capture screenshots or PDF snapshots of the views that leadership and audit teams use, and note the filters and time ranges behind each one. Rebuild the active views in Backstage or your BI tool from the exported data, and confirm with OpsLevel which report types can be downloaded in the product before the final export.
The export sequence and how to verify each step
This sequence moves services, teams, ownership and checks out of OpsLevel in a documented order, so each extract can be verified against the source before it feeds a Backstage catalog.
Inventory the catalog and record counts
Before exporting anything, the platform team lists the object types that matter: services, teams, owners, repositories, and checks or rubric results. Record the total count of each type from the OpsLevel UI and note which teams own which services. Keep this inventory in a dated file. It is done when every object type has a recorded count and an owner who has agreed to the list, so later reconciliation has a fixed baseline.
Create a read-only API token
An administrator creates a dedicated API token in OpsLevel with the narrowest read permissions the export needs, and stores it in your secrets manager rather than in a shell history or a repository. Confirm the token can read each object type from the inventory and cannot write or delete. It is done when a test read succeeds and a deliberate write attempt is refused, which you should confirm against your own OpsLevel role settings.
Run the Terraform export and CLI list commands
Using the MIT-licensed OpsLevel CLI, an engineer runs the opslevel export terraform command to generate Terraform state for existing resources, and runs list and get commands with JSON or CSV output for services, teams and checks. Write each output to its own file named by object type and date. It is done when every file exists, parses cleanly as JSON or CSV, and its row or object count matches the inventory from step one.
Page through GraphQL queries within limits
Where the CLI does not cover a field you need, an engineer queries the GraphQL API at the documented endpoint. Each query returns at most 100 results, so the script follows cursor pagination until no next page remains. It must also stay within the documented limits of 10,000 requests every 5 minutes per IP address and 400 requests per minute per API token, backing off when responses signal throttling. It is done when the paged total equals the inventory count for that type, and the script logs the request count and any retries.
Store raw extracts with checksum and date
Move the untouched output files into a versioned, access-restricted location, such as an object store in your own account. Generate a SHA-256 checksum for each file and store it in a manifest beside the data, along with the export date and the CLI or API version used. Do not edit the raw files. It is done when a second person can recompute each checksum and get the same value, which confirms the extract has not changed since it was written.
Reconcile counts against the OpsLevel UI
Compare the counts in your extracts with the counts shown in the OpsLevel interface for the same date and filters. Investigate any difference, which often comes from archived objects, filters applied in the UI, or records created during the export window. Record each difference and its explanation in the manifest. It is done when every object type either matches exactly or has a written reason for the gap that the owner has signed off.
Spot-check ownership and check results
Select a sample of services from different teams and compare each one's owner, repository, tier and check results in the extract against what the OpsLevel UI displays. Include services with failing checks and services with no owner, since those are where errors hide. Have a team lead confirm the ownership of their own services. It is done when the sampled records match and the team leads have approved the ownership data for the Backstage conversion.
Keep a dated snapshot for the cutover
Freeze the verified extract as a dated snapshot that the Backstage catalog build and any later audit can reference. Record the snapshot location, manifest and checksums in your change records, and keep it unchanged while the migration runs. If OpsLevel data changes after the snapshot, run a new dated export and reconcile it the same way rather than editing the old one. It is done when the snapshot is catalogued and a named owner accepts it as the baseline.
Mapping exported data to a Backstage catalog
Exported OpsLevel data becomes useful in Backstage only once each record is matched to a catalog kind, and the mapping is mostly about ownership. A service in OpsLevel usually maps to a Component entity, the team that owns it maps to a Group, and the people in those teams map to User entities. Where your organization groups several services into a product area, a System entity can hold the related Components. In the Backstage model, each of these is described in a YAML descriptor, conventionally named catalog-info.yaml, that sits in the repository of the thing it describes. The descriptor format is documented in the Backstage software catalog reference, and it is the document to keep open while you draft your field mapping.
Start the mapping with ownership, because that is where a wrong guess causes the most damage. Check that every Component's spec.owner value points to a Group or User that actually exists in your identity source, and decide in advance how you will handle services whose owning team has been renamed or merged in OpsLevel. If you plan to ingest Groups and Users from your identity provider, confirm which sign-in and resolver setup you will use, since Backstage's authentication guidance recommends that every provider resolve to the same identity. For API entities, the exported data may include API specifications; Backstage API entities can carry OpenAPI, AsyncAPI, GraphQL or gRPC definitions, so confirm which of these your OpsLevel records actually contain before you plan that step.
Checks and rubrics do not map one-to-one. An OpsLevel check is a rule evaluated against a service, and a Backstage catalog entity carries metadata and annotations that other plugins can read, so a check cannot simply be copied into a descriptor. Treat the exported check list as an inventory of what your organization currently measures, then decide which items become catalog facts and which need a separate evaluation mechanism. The sibling page on replacing OpsLevel maturity rubrics covers that translation in detail. Before starting, ask OpsLevel's team or review your own export to confirm which fields in your environment are populated, because gaps in ownership or tagging data will show up as empty Backstage entities.
What to plan before renewal or termination
Exporting data is the easy part when the exit plan is wrong. The decisions below set the timing, access, retention and contract conditions that decide whether your Backstage catalog starts from complete, accurate ownership data.
Set the export date early
Pick the export window well before the renewal or notice deadline, so there is time to find gaps, rerun pulls and fix missing services or teams. Run a first full export now as a baseline, then repeat it close to cutover. Compare record counts for services, teams and checks between runs. Any mismatch is a gap to resolve while OpsLevel is still the system of record, not after the subscription ends.
Confirm read access and token scope
Ask OpsLevel which API token scopes a full export needs and whether your current token already has them. The export depends on the GraphQL API, which caps results at 100 per query and applies rate limits per IP address and per API token. Confirm that a long export run will not be throttled, and confirm who can issue tokens during the exit period.
Decide retention for extracts
Exports contain service ownership, team membership and check results, which can reveal internal structure and security posture. Decide where JSON and CSV extracts are stored, who can read them, and how long they are kept after migration. Set a deletion date for working copies and record it. Keep only what the Backstage catalog and your audit trail need.
Review notice and deletion terms
Read the contract for the notice period, the data return obligations and the timeline for deleting your data after termination. Ask OpsLevel in writing how long deleted data persists in backups and whether it provides a deletion certificate. Terms vary by agreement, so confirm them against your own contract rather than relying on general practice.
Plan a parallel run
Run the Backstage catalog built from exported data alongside OpsLevel for a defined period. Compare ownership assignments and check outcomes for the same services each week, and assign one owner to resolve differences. Changes made in OpsLevel during the overlap must be copied to the catalog-info.yaml files, or ownership drifts. Cut over only when the two sources agree.
Confirm self-hosted licensing and exit timing
Self-hosting OpsLevel still requires a license file from OpsLevel, so it does not remove the subscription or its terms. Ask whether a self-hosted edition changes the exit timeline, including license expiry, Replicated requirements and how long the instance must stay reachable for push-based integrations. Build the exit plan around the license end date, not the hosting change.
Questions teams ask before exporting from OpsLevel
How much effort does a full OpsLevel export take?
Effort depends mostly on the size of the catalog, the number of checks and rubrics, and how much mapping work is needed to turn OpsLevel records into Backstage entities. The CLI can pull services, teams and check data as JSON or CSV, so the extraction step is usually the smaller part. The larger effort is deciding how each OpsLevel field maps to a catalog-info.yaml field, which entity kind each service becomes, and how checks are rebuilt. Ask OpsLevel to confirm how your account's data is exposed through the CLI and API, and run a test export against a sample of services to measure the mapping work in your own environment before agreeing on scope.
What limits the speed of an OpsLevel export through the API?
The GraphQL API returns at most 100 results per query and uses cursor pagination, so large catalogs require many sequential pages. OpsLevel also limits clients to 10,000 requests every 5 minutes per IP address and 400 requests per minute per API token. A large export that runs from one token and one IP address will be paced by these limits, so plan the job around them. The CLI's Terraform export and list commands follow the same underlying API limits. Confirm with OpsLevel whether your plan or account has different limits, and build retries and backoff into any script you write.
Can our own team run the export without outside help?
Yes, if your engineers can run the MIT-licensed OpsLevel CLI, read the GraphQL schema and write a transformation script. Many teams do the extraction in house and only bring in help for the mapping and the Backstage setup. The harder work is deciding what the new catalog should look like, which includes entity ownership, dependency relationships and how rubric checks translate into Backstage Tech Insights checks. If the team has no one who has run a Backstage catalog before, budget time for learning it. A fixed-scope engagement from DeployOpen can cover planning, implementation and documentation of the export, and the written scope will state what is included.
What access and people does the export need from us?
You need an OpsLevel API token with read permissions for the services, teams and checks you plan to export, and someone who owns that token and can rotate it after the work is done. You also need engineers who know the catalog well enough to confirm which services are current, who owns each one and which checks still matter. A staging environment for the Backstage instance is strongly advisable so mappings can be tested before production ownership data is changed. Confirm token scopes with OpsLevel, and agree in writing who signs off on the final ownership list.
How long does the migration take, and what drives the timeline?
No duration can be given without a scoped inventory, so treat any figure as provisional until your catalog is measured. The main drivers are the number of services and teams, how consistent the existing ownership data is, how many rubrics and checks must be rebuilt rather than retired, and how many integrations feed the catalog. Extra time comes from unclear ownership, duplicate services and stakeholder reviews. Ask for a timeline that separates export, mapping, Backstage setup, parallel running and cutover, so each phase can be reviewed before the next begins.
Does everything in OpsLevel export cleanly?
Not necessarily. Core entity data such as services, teams and their relationships can usually be extracted, but some data has no direct Backstage equivalent, and some features are configured in ways that need rebuilding. Maturity rubrics and checks typically need translating into Backstage facts and rule-based checks, and custom integrations, automated actions and historical scores may not carry over as they are. Review the export output for each data type, list what cannot be moved, and decide for each item whether to rebuild, retire or keep it in OpsLevel during a transition.
What happens to ownership data during the switch?
Ownership data should be treated as the most sensitive part of the move, because incident routing and accountability depend on it. Run OpsLevel and Backstage in parallel for a defined period, compare owners for each service, and resolve differences before cutting over. Keep a single source of truth at any moment, so teams do not update owners in both systems. Backstage's authentication guidance also matters here: configure sign-in resolvers so each provider resolves to the same identity, and do not allow guest access in production. Confirm with your security and compliance leads which ownership records must be retained as evidence.
How DeployOpen scopes and delivers an OpsLevel data exit
DeployOpen plans and delivers the export as a fixed-scope engagement, agreed in writing before work starts. The work covers pulling services, teams and checks out of OpsLevel, shaping them into a Backstage catalog in your own infrastructure, and documenting what moved and what did not.
How we scope
- Inventory which OpsLevel services, teams, owners and checks must move, and which can be retired.
- Confirm which export path fits your volume: the CLI Terraform export or GraphQL API with paging and rate limits.
- Agree in writing the deliverables, timelines and acceptance criteria before any export begins.
How we build
- Run the export with the OpsLevel CLI and convert results into catalog-info.yaml descriptors for Backstage.
- Test that ownership, groups and dependencies resolve correctly in a non-production Backstage instance.
- Reconcile record counts against the source so gaps are found and logged before cutover.
How we hand over
- Document the export scripts, mapping rules and known gaps, such as checks that have no direct Backstage equivalent.
- Provide a runbook for repeating the export and for keeping ownership data current during a phased switch.
- Hand over working files and configuration in your own repositories, with a walkthrough for your platform team.
How we support
- Engagements are fixed-scope, so support after handover is a separate decision.
- Ongoing support, upgrades and continuous testing are available as a retainer, scoped in writing.
- Ask for a quote based on your written scope, including who maintains the export after the project ends.

