> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rootly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Backstage

> Integrate Rootly with Spotify's Backstage developer portal to enhance service catalog management, ownership tracking, and incident response visibility.

<Frame>
  <iframe src="https://www.loom.com/embed/b890539442bb48c6ad9133ed16e7640a?sid=99d954cf-3899-4251-8c70-14fe517d4aa9" frameborder="0" allowfullscreen width="100%" height="400px" />
</Frame>

There are two ways to connect Backstage and Rootly, and they work differently:

* The **Rootly plugin for Backstage** runs inside your Backstage instance and pushes data to Rootly. It supports a rich set of `rootly.com/...` annotations for mapping entities to Rootly services, functionalities, teams, and catalog entities.
* The **built-in Backstage integration** runs on Rootly's side and pulls entities from your Backstage catalog API on a schedule. It is configured in Rootly, with one optional annotation on your Backstage entities for owner mapping.

Pick one based on where you want the configuration to live. The annotations each mode supports are different, so check the section for the mode you use. If you want to reconcile Backstage data alongside other sources like GitHub or internal APIs, the standalone [Catalog Sync CLI](/catalog-sync) is a third option.

## Rootly plugin for Backstage

The plugin is installed in your Backstage app and pushes entities to Rootly. Installation steps and the full list of supported annotations (including `rootly.com/service-id`, `rootly.com/team-slug`, auto-import, and attribute pass-through annotations) are documented in the plugin README:

[https://github.com/rootlyhq/backstage-plugin](https://github.com/rootlyhq/backstage-plugin)

## Built-in Backstage integration

The built-in integration pulls entities from your Backstage catalog API and syncs them into Rootly. To set it up:

1. In Rootly, go to **Catalogs** and click **Sync from Backstage**.
2. Enter your **Backstage API URL**, for example `https://backstage.myserver.com`.
3. Enter a **Backstage static authentication token** — a service-to-service [static token](https://backstage.io/docs/auth/service-to-service-auth/#static-tokens) from your Backstage instance.
4. Under **Kinds to import**, choose which Backstage kinds to pull, for example `Component`, `Group`, `System`, `API`. Leave it blank to import all kinds.
5. Optionally set **Filter entities to import** — a Backstage catalog API [query string](https://backstage.io/docs/features/software-catalog/software-catalog-api/#filtering) to scope the import.
6. Click **Sync from Backstage**.

### What the sync creates

Imported entities are grouped into Rootly [Catalogs](/catalogs) by their Backstage kind and type. For example, `Component` entities with `spec.type: service` land in a catalog named "Service", and `Group` entities land in a "Group" catalog.

Backstage relations such as Owner, System, `dependsOn`, and `providesApis` are stored as references between catalog entities. A reference only resolves if the entity it points to is also imported. If your components' owners show up blank, add `Group` to the entity kinds you import.

`Component` entities with `spec.type: service` can also sync into Rootly's built-in [Services](/configuration/services) catalog, so they can be used directly in escalation paths and workflows. Services are matched by name, so existing Rootly services are linked rather than duplicated.

<Info>
  Syncing into the built-in Services catalog is enabled per organization. If your components only appear in a custom catalog and not under Services, contact support to turn it on.
</Info>

### What syncs onto a service

For each Backstage component synced as a service, the integration maps:

* **Name** and **description** from the entity's metadata.
* **Owning team**, resolved in this order:
  1. A `rootly.com/team-slug` annotation on the component, matched against a Rootly team's slug.
  2. The entity's `spec.owner` reference, matched against a Rootly team that has the corresponding Backstage ID set.

Owner syncing is additive: the sync adds the Backstage owner if it isn't already linked, and never removes teams you set in Rootly.

Other service fields, such as environments, escalation policy, and notification settings, are not synced from Backstage. Set them in the Rootly UI or via the [API](/api-reference/overview). They persist across re-syncs. For example, to set environments on a service:

```bash theme={null}
curl --request PUT \
  --url https://api.rootly.com/v1/services/{service_id} \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
    "data": {
      "type": "services",
      "attributes": {
        "environment_ids": ["your-environment-uuid"]
      }
    }
  }'
```

<Warning>
  **Deleting an entity in Backstage deletes the matching synced service in Rootly** on the next sync. If you remove a component from Backstage but want to keep the service, recreate it in Rootly without a Backstage link.
</Warning>

### Map owners with the team-slug annotation

The built-in integration reads one annotation from your Backstage entities: `rootly.com/team-slug`. Add it to a component to link the synced service to a Rootly team:

```yaml theme={null}
metadata:
  annotations:
    rootly.com/team-slug: infrastructure-platform
```

The value must match the team's slug in Rootly exactly. Owner matching does not fall back to name matching.

<Note>
  The other `rootly.com/...` annotations documented in the plugin README, including the `service-attr-...` attribute pass-through annotations, apply only to the Rootly plugin for Backstage. The built-in integration ignores them.
</Note>

### Scope the import with filters

The entity filter uses Backstage's catalog API filter syntax: conditions inside one `filter` parameter are combined with AND, and separate `filter` parameters are combined with OR. For example, to import production service components and all groups:

```text theme={null}
filter=kind=component,spec.type=service,spec.lifecycle=production&filter=kind=group
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Owner or System is blank on imported entities">
    The referenced entity was not imported, so the reference has nothing to resolve to. Add the referenced kind (usually `Group` or `System`) to the entity kinds you import, and make sure your filter doesn't exclude it, then re-sync.
  </Accordion>

  <Accordion title="Annotations on my components are being ignored">
    The built-in integration only reads `rootly.com/team-slug`. The other annotations in the plugin README, including `service-attr-...`, only work with the Rootly plugin for Backstage. Set those fields in the Rootly UI or via the API instead.
  </Accordion>

  <Accordion title="Services appear in a custom catalog instead of the built-in Services catalog">
    Syncing components into the built-in Services catalog is enabled per organization. Contact support to enable it, then re-sync. Existing services are matched by name, so nothing gets duplicated.
  </Accordion>

  <Accordion title="A service is &#x22;Owned by&#x22; a team in the catalog but has no owning team">
    The catalog entity's Owner reference and the service's owning team are set separately. The owning team on a service requires the `rootly.com/team-slug` annotation or a `spec.owner` reference that matches a Rootly team's Backstage ID.
  </Accordion>
</AccordionGroup>

## Related

* [Catalogs](/catalogs)
* [Services](/configuration/services)
* [Catalog Sync CLI](/catalog-sync)
