Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@
"integrations/all/outlook",
"integrations/all/outreach",
"integrations/all/pagerduty",
"integrations/all/passportal",
"integrations/all/pandadoc",
"integrations/all/pandadoc-api-key",
"integrations/all/payfit",
Expand Down
92 changes: 92 additions & 0 deletions docs/integrations/all/passportal.mdx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a new docs style,take a look at Sellsy (Client Credentials) as an example.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved to this new style.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: 'Passportal'
sidebarTitle: 'Passportal'
description: 'Connect to the Passportal API in 2 minutes 💨'
---

<Tabs>
<Tab title="🚀 Quickstart">
<Steps>
<Step title="Create an integration">
Sign up for a free Nango account ([here](https://app.nango.dev)) if you haven't already. Then navigate to [Integrations](https://app.nango.dev/dev/integrations) -> _Configure New Integration_ -> select _Passportal_.
</Step>

<Step title="Authorize Passportal">
Go to [Connections](https://app.nango.dev/dev/connections) -> _Add Test Connection_ -> _Authorize_, then enter your Passportal **API Access Key ID**, **HMAC Token**, **Content String**, and **Base URL**. Later, you'll let your users do the same directly from your app.
</Step>

<Step title="Call the Passportal API">
Let's make your first request to Passportal (fetch a list of clients). Replace the placeholders below with your [Nango secret key](https://app.nango.dev/dev/environment-settings), [integration ID](https://app.nango.dev/dev/integrations), and [connection ID](https://app.nango.dev/dev/connections):

<Tabs>
<Tab title="cURL">
```bash
curl -X GET "https://api.nango.dev/proxy/api/v2/clients" \
-H "Authorization: Bearer <NANGO-SECRET-KEY>" \
-H "Provider-Config-Key: <INTEGRATION-ID>" \
-H "Connection-Id: <CONNECTION-ID>" \
-H "Accept: application/json"
```
</Tab>

<Tab title="Node">
Install Nango's backend SDK: `npm i @nangohq/node`. Then run:

```typescript
import { Nango } from '@nangohq/node';

const nango = new Nango({ secretKey: '<NANGO-SECRET-KEY>' });

// Fetch a list of clients from Passportal
const res = await nango.get({
endpoint: '/api/v2/clients',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>'
});

console.log(res.data);
```
</Tab>
</Tabs>

You can also fetch credentials dynamically via the [Node SDK](/reference/sdks/node#get-a-connection-with-credentials) or [API](/reference/api/connection/get).
</Step>
</Steps>

✅ You're connected! Check the [Logs](https://app.nango.dev/dev/logs) tab in Nango to inspect requests.

<Tip>
Next step: [Embed the auth flow](/getting-started/quickstart/embed-in-your-app) in your app to let your users connect their Passportal accounts.
</Tip>
</Tab>

<Tab title="🔗 Useful links">
| Topic | Links |
| - | - |
| Authorization | [Guide to connect to Passportal using Connect UI](/integrations/all/passportal/connect) |
| General | [Passportal Website](https://www.n-able.com/products/passportal) |
| Developer | [Passportal API Documentation](https://documentation.n-able.com/passportal/userguide/Content/api/api_information.htm) |
| | [API Key Management Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_key_management.htm) |
| | [Create HMAC Token Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_create_hmac.htm) |
| | [Generate API Access Token](https://documentation.n-able.com/passportal/userguide/Content/api/api_authorization.htm) |

<Note>Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs/integrations/all/passportal.mdx)</Note>
</Tab>

<Tab title="🚨 API gotchas">
- Passportal uses instance-specific base URLs (e.g., `mycompany.passportalmsp.com`)
- Authentication requires a POST request to `/api/v2/auth/client_token` with the API Access Key ID in the `x-key` header
- The `x-hash` header must contain a pre-generated HMAC-SHA256 token (hexadecimal hash)
- Generate your HMAC token offline before configuring the integration
- You must provide the same content string that was used to generate the HMAC token in the request body
- The token request must include `scope: "docs_api"` in the body
- The access token expires and should be refreshed using the provided refresh token
- All API requests must include the access token in the Authorization Bearer header

<Note>Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs/integrations/all/passportal.mdx)</Note>
</Tab>
</Tabs>

<Info>
Questions? Join us in the [Slack community](https://nango.dev/slack).
</Info>
79 changes: 79 additions & 0 deletions docs/integrations/all/passportal/connect.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: Passportal - How do I link my account?
sidebarTitle: Passportal
---

# Overview

To authenticate with Passportal, you need:
1. **API Access Key ID** – Your Passportal API Access Key ID.
2. **HMAC Token** – A pre-generated HMAC-SHA256 hash token (base64 encoded).
3. **Content String** – The plain text message used to compute the HMAC token.
4. **Base URL** – Your Passportal instance domain (e.g., `mycompany.passportalmsp.com`).

This guide walks you through generating your API credentials and HMAC token for Passportal.

### Prerequisites:

- Access to your Passportal account with API permissions.

### Step 1: Find your Passportal base URL

Log into your Passportal dashboard, check the URL at your browser address bar.
If your URL is `https://mycompany.passportalmsp.com/dashboard` → Your Base URL is
`mycompany.passportalmsp.com`

### Step 2: Generate API Access Key ID and Secret Access Key

1. Log into your Passportal dashboard.
2. In the left pane, go to **Settings** > **API Keys**.
<img src="/integrations/all/passportal/passportal-settings.png"/>
3. Click **Create access key**.
<img src="/integrations/all/passportal/passportal-api-keys.png"/>
4. View the **Access key ID**, then click **Show key** to reveal the **Secret access key**.
<img src="/integrations/all/passportal/passportal-new-key.png"/>
5. Copy both the **Access key ID** and **Secret access key** to a secure location.

**Important**: The Secret access key is only viewable once in the Create access key dialog. After closing this dialog, it cannot be retrieved again.

<img src="/integrations/all/passportal/api-keys.png"/>

See: [API Key Management Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_key_management.htm)

### Step 3: Generate HMAC Token

You need to create an HMAC-SHA256 token using:
- **Plain text message**: Choose a content string (e.g., `api-content-hash`). This text is not considered sensitive
- **Secret key**: Your Secret access key from Step 2
- **Algorithm**: SHA-256

Generate the HMAC token using Python:

```python
import hmac
import hashlib

secret_key = "YOUR_SECRET_ACCESS_KEY"
content = "api-content-hash"
hmac_token = hmac.new(secret_key.encode(), content.encode(), hashlib.sha256).hexdigest()
print(hmac_token)
```

Store both the **HMAC token** and the **content string** you used – you'll need both.

See: [Create HMAC Token Guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_create_hmac.htm)

### Step 4: Enter your details in the Connect UI

Once you have your **API Access Key ID**, **HMAC Token**, **Content String**, and **Base URL**:
1. Open the form where you connect to Passportal.
2. Enter your **API Access Key ID**.
3. Enter your **HMAC Token** (the hexadecimal hash you generated).
4. Enter your **Content String** (the same text you used to generate the HMAC token, e.g., `api-content-hash`).
5. Enter your **Base URL** (e.g., `mycompany.passportalmsp.com`).
6. Click **Connect**.

<img src="/integrations/all/passportal/passportal-auth-form.png"/>

You are now connected to Passportal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to include the form screenshot.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions docs/snippets/generated/passportal/PreBuiltTooling.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Pre-built tooling
<AccordionGroup>
<Accordion title="✅ Authorization">
| Tools | Status |
| - | - |
| Pre-built authorization (Two Step) ||
| Pre-built authorization UI ||
| Custom authorization UI ||
| End-user authorization guide ||
| Expired credentials detection ||
</Accordion>
<Accordion title="✅ Read & write data">
| Tools | Status |
| - | - |
| Pre-built integrations | 🚫 (time to contribute: &lt;48h) |
| API unification ||
| 2-way sync ||
| Webhooks from Nango on data modifications ||
| Real-time webhooks from 3rd-party API | 🚫 (time to contribute: &lt;48h) |
| Proxy requests ||
</Accordion>
<Accordion title="✅ Observability & data quality">
| Tools | Status |
| - | - |
| HTTP request logging ||
| End-to-type type safety ||
| Data runtime validation ||
| OpenTelemetry export ||
| Slack alerts on errors ||
| Integration status API ||
</Accordion>
<Accordion title="✅ Customization">
| Tools | Status |
| - | - |
| Create or customize use-cases ||
| Pre-configured pagination | 🚫 (time to contribute: &lt;48h) |
| Pre-configured rate-limit handling | 🚫 (time to contribute: &lt;48h) |
| Per-customer configurations ||
</Accordion>
</AccordionGroup>
5 changes: 5 additions & 0 deletions docs/snippets/generated/passportal/PreBuiltUseCases.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Pre-built integrations

_No pre-built integration yet (time to contribute: &lt;48h)_

<Tip>Not seeing the integration you need? [Build your own](https://nango.dev/docs/guides/platform/functions) independently.</Tip>
60 changes: 60 additions & 0 deletions packages/providers/providers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9187,6 +9187,66 @@ pandadoc-api-key:
example: 3039ba033eb1410caa0a2227158d63c9d6502cd8
pattern: '^[a-fA-F0-9]+$'

passportal:
display_name: Passportal
categories:
- support
auth_mode: TWO_STEP
token_url: https://${connectionConfig.base_url}/api/v2/auth/client_token
token_headers:
x-key: ${credentials.apiKey}
x-hash: ${credentials.hmacToken}
content-type: application/json
token_params:
scope: docs_api
content: ${credentials.content}
token_response:
token: access_token
token_expiration: expiry_time
token_expiration_strategy: expireAt
proxy:
base_url: https://${connectionConfig.base_url}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the base_url always have a suffix passportalmsp.com, if so you can just request for the subdomain instead. with prefix: https:// and suffix : passportalmsp.com

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the base_url is not constrained to a single suffix; Passportal's documentation shows a different suffix to our domain's suffix.

headers:
authorization: Bearer ${accessToken}
verification:
method: GET
headers:
content-type: application/json
endpoints:
- /api/v2/documents?resultsPerPage=1
connection_config:
base_url:
type: string
title: Passportal Base URL
description: Your Passportal base URL
example: mycompany.mypasswordapp.com
format: hostname
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
format: hostname
format: hostname
prefix: https://

doc_section: '#step-1-find-your-passportal-base-url'
credentials:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to a add an example and pattern for both apiKey and hmacToken.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I've added these.

apiKey:
type: string
title: API Access Key ID
description: Your Passportal API Access Key ID
example: a14e6b4923ba5027189baded6ba7b68e6fcda742008c5d57b867f43a09768ece
pattern: '^[a-fA-F0-9]{64}$'
doc_section: '#step-2-generate-api-access-key-id-and-secret-access-key'
hmacToken:
type: string
title: HMAC Token
description: Your pre-generated HMAC token, hex encoded
example: 23ec313efecb560a7f44239f6dd439ea56d18911c18b59e1150a3c7299da8202
pattern: '^[a-fA-F0-9]{64}$'
secret: true
doc_section: '#step-3-generate-hmac-token'
content:
type: string
title: Content String
description: Plain text message used to compute the HMAC token
example: api-content-hash
doc_section: '#step-3-generate-hmac-token'
docs: https://nango.dev/docs/integrations/all/passportal
docs_connect: https://nango.dev/docs/integrations/all/passportal/connect

paychex:
display_name: Paychex
categories:
Expand Down
10 changes: 10 additions & 0 deletions packages/webapp/public/images/template-logos/passportal.svg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the logo should have a maximum width or height of 44px and be centered within a 62x62px container.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Claude Code is to be believed, the SVG should now meet these requirements.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.