Zapier
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 Zapier integration lets you ingest Zapier apps and zaps into your software catalog using the Ocean Custom Integration framework.
Overview
This guide shows how to ingest Zapier apps and zaps into Port.
Supported resources
This integration ingests the following resources:
zapierAppfrom theGET /v2/appsendpoint.zapfrom theGET /v2/zapsendpoint.
It is possible to reference any field that appears in the API responses linked above in the mapping configuration.
Prerequisites
To use this integration, make sure you have:
- A Zapier account with API access.
- A Port client ID and client secret.
- Permission to create blueprints and data-source mappings in Port.
Authentication
Zapier allows two authentication methods for this setup:
- OAuth 2.0 Authorization Code flow (rolling refresh tokens).
- Client id passed as a query parameter.
User access token authentication
Zapier refresh tokens rotate: every refresh request can return a new refresh token and immediately invalidate the old one.
To keep sync working, you need an external workflow that refreshes tokens and updates the new refresh token in your Port secrets every time it changes.
Automate token refresh with GitHub Actions
You can use this scheduled GitHub Actions workflow to refresh your Zapier token and update repository secrets.
- Add these repository secrets:
ZAPIER_CLIENT_ID,ZAPIER_CLIENT_SECRET,ZAPIER_OAUTH_REFRESH_TOKEN, andGH_ADMIN_TOKEN. - Set
GH_ADMIN_TOKENto a GitHub personal access token with permission to update repository secrets. - Reference
ZAPIER_OAUTH_ACCESS_TOKENin your integration runtime.
GitHub Actions workflow example (Click to expand)
name: Refresh Zapier OAuth token
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
jobs:
refresh-token:
runs-on: ubuntu-latest
steps:
- name: Refresh Zapier access token
id: refresh
env:
CLIENT_ID: ${{ secrets.ZAPIER_CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.ZAPIER_CLIENT_SECRET }}
REFRESH_TOKEN: ${{ secrets.ZAPIER_OAUTH_REFRESH_TOKEN }}
run: |
response=$(curl -sS -X POST "https://api.zapier.com/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "refresh_token=$REFRESH_TOKEN")
access_token=$(echo "$response" | jq -r '.access_token')
refresh_token=$(echo "$response" | jq -r '.refresh_token')
if [ -z "$access_token" ] || [ "$access_token" = "null" ]; then
echo "Failed to refresh token: $response"
exit 1
fi
echo "access_token=$access_token" >> "$GITHUB_OUTPUT"
echo "refresh_token=$refresh_token" >> "$GITHUB_OUTPUT"
- name: Update GitHub secrets
env:
GH_TOKEN: ${{ secrets.GH_ADMIN_TOKEN }}
ACCESS_TOKEN: ${{ steps.refresh.outputs.access_token }}
REFRESH_TOKEN: ${{ steps.refresh.outputs.refresh_token }}
run: |
gh secret set ZAPIER_OAUTH_ACCESS_TOKEN --body "$ACCESS_TOKEN"
gh secret set ZAPIER_OAUTH_REFRESH_TOKEN --body "$REFRESH_TOKEN"
Client ID Authentication
The GET /v2/apps endpoint requires a client_id query parameter and does not require OAuth.
In Ocean custom integration mappings, query params are typically not backed by Port secrets. Treat client_id as configuration and avoid placing sensitive values directly in mapping fields.
Set up data model
Before data can sync, create the required blueprints in Port:
- Open the Builder page.
- Create blueprints for
zapierAppandzap. - Copy and paste each blueprint JSON from the sections below.
- Click Save.
Zapier app blueprint (Click to expand)
{
"identifier": "zapierApp",
"title": "Zapier App",
"icon": "Zapier",
"schema": {
"properties": {
"description": {
"title": "Description",
"type": "string"
},
"image": {
"title": "Image",
"type": "string",
"format": "url"
},
"hex_color": {
"title": "Hex Color",
"type": "string"
},
"action_types": {
"title": "Action Types",
"type": "array"
},
"categories": {
"title": "Categories",
"type": "array"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Zap blueprint (Click to expand)
{
"identifier": "zap",
"title": "Zap",
"icon": "Zapier",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string"
},
"url": {
"title": "Zap URL",
"type": "string",
"format": "url"
},
"modified_at": {
"title": "Modified At",
"type": "string",
"format": "date-time"
},
"trigger_app": {
"title": "Trigger App",
"type": "string"
},
"action_apps": {
"title": "Action Apps",
"type": "array"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Installation
Choose one of the following installation methods to deploy the Ocean custom integration:
- Helm
- Docker
- Hosted by Port
Prerequisites
-
A Kubernetes cluster - the integration's container chart will be deployed to this cluster.
-
kubectlandhelmmust be installed on your machine. YourkubectlCLI must be connected to the Kubernetes cluster where you plan to install the integration.
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_ZAPIER_OAUTH_ACCESS_TOKEN.
helm repo add --force-update port-labs https://port-labs.github.io/helm-charts
helm upgrade --install my-ocean-zapier-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=false \
--set scheduledResyncInterval=60 \
--set integration.identifier="my-ocean-zapier-integration" \
--set integration.type="custom" \
--set integration.eventListener.type="POLLING" \
--set integration.config.baseUrl="https://api.zapier.com" \
--set integration.config.authType="bearer_token" \
--set integration.config.apiToken="YOUR_ZAPIER_OAUTH_ACCESS_TOKEN" \
--set integration.config.paginationType="link" \
--set integration.config.nextLinkPath="links.next"
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
Configuration parameters
| 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 | Zapier API base URL. | https://api.zapier.com | ✅ |
integration.config.authType | The authentication type for the API. Use bearer_token when you authenticate with an OAuth access token. | bearer_token | ✅ |
integration.config.apiToken | Zapier OAuth access token to use in Authorization: Bearer <token>. | ✅ | |
integration.config.paginationType | Pagination strategy. Use link to follow the next URL in Zapier responses. | link | ✅ |
integration.config.nextLinkPath | Path to the next page URL in the response body for link pagination. | links.next | ✅ |
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-zapier-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. | 60 | ❌ |
initializePortResources | When set to true the integration will create default blueprints and mapping automatically. For this guide, you set it to false and create blueprints and mappings manually. | false | ❌ |
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_ZAPIER_OAUTH_ACCESS_TOKEN.
docker run -i --rm --platform=linux/amd64 \
-e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
-e OCEAN__INITIALIZE_PORT_RESOURCES=false \
-e OCEAN__SEND_RAW_DATA_EXAMPLES=true \
-e OCEAN__INTEGRATION__CONFIG__BASE_URL="https://api.zapier.com" \
-e OCEAN__INTEGRATION__CONFIG__AUTH_TYPE="bearer_token" \
-e OCEAN__INTEGRATION__CONFIG__API_TOKEN="YOUR_ZAPIER_OAUTH_ACCESS_TOKEN" \
-e OCEAN__INTEGRATION__CONFIG__PAGINATION_TYPE="link" \
-e OCEAN__INTEGRATION__CONFIG__NEXT_LINK_PATH="links.next" \
-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 select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
For advanced configuration such as proxies or self-signed certificates, click here.
Set up in Port
- Go to the custom data source page.
- Click + Data source and choose Ocean custom integration.
- In the configuration form, enter the following values:
- Identifier:
my-ocean-zapier-integration. - Base URL:
https://api.zapier.com. - Authentication type:
bearer_token. - Token: your Zapier OAuth access token.
- Pagination type:
link. - Next link path:
links.next.
- Identifier:
- Click Save & install.
Resource mappings
Use the mappings below to ingest Zapier apps and zaps.
Zapier apps
resources:
- kind: /v2/apps
selector:
query: 'true'
data_path: '.data'
query_params:
client_id: "<YOUR_CLIENT_ID>"
port:
entity:
mappings:
identifier: .id
title: .title
blueprint: '"zapierApp"'
properties:
description: .description
image: .image
hex_color: .hex_color
action_types: .action_types
categories: '[.categories[].slug]'
Zaps
resources:
- kind: /v2/zaps
selector:
query: 'true'
data_path: '.data'
port:
entity:
mappings:
identifier: .id
title: .title
blueprint: '"zap"'
properties:
state: .is_enabled
url: .links.html_editor
modified_at: .updated_at
trigger_app: '[.steps[] | select(.type_of == "read")] | first | .app.title'
action_apps: '[.steps[] | select(.type_of == "write") | .app.title]'
Configuration
After installation, configure mappings in Port so Ocean can transform Zapier API responses into Port entities.
The mapping resources[].kind must match the endpoint path you want to call, relative to your OCEAN__INTEGRATION__CONFIG__BASE_URL.
You can use JQ expressions in mappings to filter, reshape, and enrich Zapier data before sync.
Next step
Once you pick your exact Zapier endpoints and blueprint schema, update the resources[] mappings to match the real request and response payloads from your Zapier account.