Rootly
This integration was created using the custom Ocean integration builder.
Please note that:
- This integration will not be listed in the
Data sourcespage of your Port application, and must be installed manually using the instructions on this page. - This integration will not create components (e.g.
blueprints,mapping, etc.) in your portal automatically, you will need to create them manually using the instructions on this page.
Port's Rootly integration allows you to ingest Rootly incident management resources into your software catalog using the Ocean Custom Integration framework. After installing this integration, you would be able to visualize your Rootly incidents, services, teams, and on-call schedules using Port's dashboards.
Supported resources
The Rootly integration can ingest the following resources into Port. It is possible to reference any field that appears in the API responses in the mapping configuration. For detailed API documentation, see the Rootly API documentation.
- Incidents - Incident records and their details from
/incidents. - Services - Service catalog entries from
/services. - Teams - Team information from
/teams. - Users - User accounts from
/users. - Environments - Environment configurations from
/environments. - Severities - Incident severity levels from
/severities. - Functionalities - Functionality catalog from
/functionalities.
Prerequisites
To use this integration, you need:
- A Rootly API key with appropriate permissions to access incident and catalog data.
- The API key should have read access to incidents, services, teams, and other resources you want to sync.
Create a Rootly API key
- Log in to your Rootly account.
- Click on your Organization dropdown in the top navigation.
- Select Organization Settings.
- Navigate to API Keys in the left sidebar.
- Click Generate New API Key.
- Select the appropriate API key type:
- Global API Key - Full access to all entities (recommended for integration).
- Team API Key - Limited to specific team resources.
- Personal API Key - Inherits your user permissions.
- Provide a name for your API key (e.g., "Port Integration").
- Click Generate.
- Copy the API key immediately and save it securely.
Store your API key securely and never share it. The key provides access to your Rootly data.
Installation
Choose one of the following installation methods to deploy the Ocean Custom Integration:
- Helm
- Docker
Prerequisites
To install the integration, you need a Kubernetes cluster that the integration's container chart will be deployed to.
Please make sure that you have kubectl and helm installed on your machine, and that your kubectl CLI is connected to the Kubernetes cluster where you plan to install the integration.
If you are having trouble installing this integration, please refer to these troubleshooting steps.
Installation
Add Port's Helm repo and install the Ocean Custom Integration:
Remember to replace the placeholders for YOUR_PORT_CLIENT_ID, YOUR_PORT_CLIENT_SECRET, and YOUR_ROOTLY_API_KEY.
helm repo add --force-update port-labs https://port-labs.github.io/helm-charts
helm upgrade --install my-ocean-rootly-integration port-labs/port-ocean \
--set port.clientId="YOUR_PORT_CLIENT_ID" \
--set port.clientSecret="YOUR_PORT_CLIENT_SECRET" \
--set port.baseUrl="https://api.getport.io" \
--set initializePortResources=true \
--set scheduledResyncInterval=120 \
--set integration.identifier="my-ocean-rootly-integration" \
--set integration.type="custom" \
--set integration.eventListener.type="POLLING" \
--set integration.config.baseUrl="https://api.rootly.com/v1" \
--set integration.config.authType="bearer_token" \
--set integration.config.paginationType="page" \
--set integration.config.apiToken="YOUR_ROOTLY_API_KEY"
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance of Port API will be used.
Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.
- If you use the EU region of Port (https://app.port.io), your API URL is
https://api.port.io. - If you use the US region of Port (https://app.us.port.io), your API URL is
https://api.us.port.io.
Configuration parameters
This table summarizes the available parameters for the installation.
| Parameter | Description | Example | Required |
|---|---|---|---|
port.clientId | Your Port client id | ✅ | |
port.clientSecret | Your Port client secret | ✅ | |
port.baseUrl | Your Port API URL - https://api.getport.io for EU, https://api.us.getport.io for US | ✅ | |
integration.config.baseUrl | The base URL of the Rootly API instance | https://api.rootly.com/v1 | ✅ |
integration.config.authType | The authentication type for the API (use bearer_token for Rootly) | bearer_token | ✅ |
integration.config.apiToken | Your Rootly API key | ✅ | |
integration.config.paginationType | How your API handles pagination (offset, page, cursor, or none) | page | ❌ |
integration.eventListener.type | The event listener type. Read more about event listeners | POLLING | ✅ |
integration.type | The integration type (must be custom for Ocean Custom Integration) | custom | ✅ |
integration.identifier | Unique identifier for the integration instance | my-ocean-rootly-integration | ✅ |
scheduledResyncInterval | The number of minutes between each resync. When not set the integration will resync for each event listener resync event. Read more about scheduledResyncInterval | 120 | ❌ |
initializePortResources | Default true, When set to true the integration will create default blueprints and the port App config Mapping. Read more about initializePortResources | true | ❌ |
sendRawDataExamples | Enable sending raw data examples from the third party API to port for testing and managing the integration mapping. Default is true | true | ❌ |
For advanced configuration such as proxies or self-signed certificates, click here.
To run the integration using Docker for a one-time sync:
Remember to replace the placeholders for YOUR_PORT_CLIENT_ID, YOUR_PORT_CLIENT_SECRET, and YOUR_ROOTLY_API_KEY.
docker run -i --rm --platform=linux/amd64 \
-e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
-e OCEAN__INITIALIZE_PORT_RESOURCES=true \
-e OCEAN__SEND_RAW_DATA_EXAMPLES=true \
-e OCEAN__INTEGRATION__CONFIG__BASE_URL="https://api.rootly.com/v1" \
-e OCEAN__INTEGRATION__CONFIG__AUTH_TYPE="bearer_token" \
-e OCEAN__INTEGRATION__CONFIG__PAGINATION_TYPE="page" \
-e OCEAN__INTEGRATION__CONFIG__API_TOKEN="YOUR_ROOTLY_API_KEY" \
-e OCEAN__PORT__CLIENT_ID="YOUR_PORT_CLIENT_ID" \
-e OCEAN__PORT__CLIENT_SECRET="YOUR_PORT_CLIENT_SECRET" \
-e OCEAN__PORT__BASE_URL="https://api.getport.io" \
ghcr.io/port-labs/port-ocean-custom:latest
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance of Port API will be used.
Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.
- If you use the EU region of Port (https://app.port.io), your API URL is
https://api.port.io. - If you use the US region of Port (https://app.us.port.io), your API URL is
https://api.us.port.io.
For advanced configuration such as proxies or self-signed certificates, click here.
Set up data model
Before the integration can sync data, you need to create the required blueprints in Port. These blueprints define the data model for your Rootly resources.
To create the blueprints:
-
Go to your Builder page.
-
Click on the
+ Blueprintbutton. -
Copy and paste each blueprint JSON from the sections below.
Rootly Incident Blueprint (Click to expand)
Incident records and their details:
{
"identifier": "rootly-incident",
"title": "Rootly Incident",
"icon": "Rootly",
"schema": {
"properties": {
"title": {
"title": "Title",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
},
"severity": {
"title": "Severity",
"type": "string"
},
"started_at": {
"title": "Started At",
"type": "string",
"format": "date-time"
},
"resolved_at": {
"title": "Resolved At",
"type": "string",
"format": "date-time"
},
"url": {
"title": "Incident URL",
"type": "string",
"format": "url"
},
"summary": {
"title": "Summary",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}Rootly Service Blueprint (Click to expand)
Service catalog entries:
{
"identifier": "rootly-service",
"title": "Rootly Service",
"icon": "Rootly",
"schema": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"slug": {
"title": "Slug",
"type": "string"
},
"color": {
"title": "Color",
"type": "string"
},
"notify_emails": {
"title": "Notify Emails",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}Rootly Team Blueprint (Click to expand)
Team information:
{
"identifier": "rootly-team",
"title": "Rootly Team",
"icon": "Team",
"schema": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"slug": {
"title": "Slug",
"type": "string"
},
"color": {
"title": "Color",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}Rootly User Blueprint (Click to expand)
User accounts:
{
"identifier": "rootly-user",
"title": "Rootly User",
"icon": "User",
"schema": {
"properties": {
"email": {
"title": "Email",
"type": "string",
"format": "email"
},
"full_name": {
"title": "Full Name",
"type": "string"
},
"role": {
"title": "Role",
"type": "string"
},
"accepted_invite_at": {
"title": "Accepted Invite At",
"type": "string",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
} -
Click
Saveto save the blueprint.
Configuration
After installation, define which endpoints to sync in your integration configuration. Each resource maps an API endpoint to Port entities using JQ expressions to transform the data.
Key mapping components:
kind: The API endpoint path (combined with your base URL).selector.query: JQ filter to include/exclude entities (use'true'to sync all).selector.data_path: JQ expression pointing to the array of items in the response.port.entity.mappings: How to map API fields to Port entity properties.
For more details on how the Ocean Custom Integration works, see the How it works section in the custom integration overview.
To configure the mappings:
-
Go to your data sources page.
-
Find your Rootly integration in the list.
-
Click on the integration to open the mapping editor.
-
Add the resource mapping configurations below.
Incidents mapping (Click to expand)
resources:
- kind: /incidents
selector:
query: 'true'
data_path: '.data'
query_params:
page[size]: "100"
port:
entity:
mappings:
identifier: .id
title: .attributes.title
blueprint: '"rootly-incident"'
properties:
title: .attributes.title
status: .attributes.status
severity: .attributes.severity.data.attributes.severity
started_at: .attributes.started_at
resolved_at: .attributes.resolved_at
url: .attributes.url
summary: .attributes.summaryRootly API response formatRootly uses the JSON:API specification, so responses are structured with
dataarrays containing objects withid,type, andattributesfields. Use.dataas thedata_pathand reference fields via.attributes.fieldName.Services mapping (Click to expand)
resources:
- kind: /services
selector:
query: 'true'
data_path: '.data'
query_params:
page[size]: "100"
port:
entity:
mappings:
identifier: .id
title: .attributes.name
blueprint: '"rootly-service"'
properties:
name: .attributes.name
description: .attributes.description
slug: .attributes.slug
color: .attributes.color
notify_emails: .attributes.notify_emailsTeams mapping (Click to expand)
resources:
- kind: /teams
selector:
query: 'true'
data_path: '.data'
query_params:
page[size]: "100"
port:
entity:
mappings:
identifier: .id
title: .attributes.name
blueprint: '"rootly-team"'
properties:
name: .attributes.name
description: .attributes.description
slug: .attributes.slug
color: .attributes.colorUsers mapping (Click to expand)
resources:
- kind: /users
selector:
query: 'true'
data_path: '.data'
query_params:
page[size]: "100"
port:
entity:
mappings:
identifier: .id
title: .attributes.full_name // .attributes.email
blueprint: '"rootly-user"'
properties:
email: .attributes.email
full_name: .attributes.full_name
role: .attributes.role
accepted_invite_at: .attributes.accepted_invite_at -
Click
Saveto save the mapping.
Customization
If you want to customize your setup or test different API endpoints before committing to a configuration, use the interactive builder.
The interactive builder helps you:
- Test your Rootly API endpoints with live data.
- Automatically detect the data structure and field types.
- Generate blueprints and resource mappings tailored to your preferences.
- Get installation commands with your configuration pre-filled.
Simply provide your Rootly API details, and the builder will generate everything you need to install and create the integration in Port.
Troubleshooting
Common issues
- Authentication Errors: Verify your Rootly API key has the correct permissions and is not expired. Ensure you're using a Global API Key for full access to all resources.
- Rate Limiting: Rootly has API rate limits (3000 requests per minute per API key). The integration handles this automatically with retries. If you encounter frequent rate limit errors, consider reducing the sync frequency.
- Data Path Issues: Rootly uses the JSON:API specification, so all responses have a
dataarray. Ensure yourdata_pathis set to.datafor all endpoints. - Pagination: Rootly uses page-based pagination with
page[number]andpage[size]parameters. The integration handles this automatically whenpaginationTypeis set topage. - Empty Responses: If you're getting empty data, verify that your Rootly account has the resources you're trying to sync (incidents, services, teams, etc.).
Limitations
- The integration currently supports polling-based sync only (no real-time webhooks).
- Rate limits apply (3000 requests per minute per API key).
- Some Rootly resources may require specific permissions or subscription tiers.
- The integration uses the JSON:API specification format, which structures responses differently from standard REST APIs.