Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
94 changes: 94 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,94 @@
---
title: Passportal
sidebarTitle: Passportal
---

import Overview from "/snippets/overview.mdx"
import PreBuiltTooling from "/snippets/generated/passportal/PreBuiltTooling.mdx"
import PreBuiltUseCases from "/snippets/generated/passportal/PreBuiltUseCases.mdx"

<Overview />
<PreBuiltTooling />
<PreBuiltUseCases />

## Access requirements
| Pre-Requisites | Status | Comment|
| - | - | - |
| Paid dev account || Passportal account required for API access |
| Paid test account || Passportal account required for testing |
| Partnership || Not required |
| App review || Not required |
| Security audit || Not required |

## Setup guide
<Steps>
<Step title="Create a Passportal account">
Sign up for a [Passportal account](https://www.n-able.com/products/passportal) if you don't already have one.
</Step>
<Step title="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**
3. Click **Create access key**
4. View the **Access key ID** then click **Show key** to reveal the **Secret access key**
5. Copy both the **Access key ID** and **Secret access key** to a secure location

**Important**: The Secret access key is only viewable in the Create access key dialog. After closing this dialog, the Secret access key is no longer accessible.

See the [API Key Management guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_key_management.htm) for more details.
</Step>
<Step title="Generate HMAC Token">
You need to create an HMAC-SHA256 token using:
- **Plain text message**: Choose a content string (e.g., 'api-content-hash')
- **Secret key**: Your Secret access key from the previous step
- **Algorithm**: SHA-256

You can 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)
```

Or using an online HMAC generator:
1. Use an HMAC generator (many are available online)
2. Enter your chosen content string as the message
3. Enter your Secret access key as the key
4. Select SHA-256 as the algorithm
5. Generate the HMAC hash in hexadecimal form
6. Store the HMAC token securely

_Note: online HMAC generators are not recommended - what if the website has been secretly compromised?_

See the [Create HMAC Token guide](https://documentation.n-able.com/passportal/userguide/Content/api/api_create_hmac.htm) for more details.
</Step>
<Step title="Next">
Follow the [_Quickstart_](/getting-started/quickstart).
</Step>
</Steps>

## Useful links

- [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>

## API gotchas

- Passportal uses instance-specific base URLs. Example: `mycompany.mypasswordapp.com` or `instance.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 (hash of content string, base64 encoded)
- 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>
78 changes: 78 additions & 0 deletions docs/integrations/all/passportal/connect.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Passportal - How do I link my account?
sidebarTitle: Passportal
---

# Overview

To authenticate with Passportal, you need:
1. **Base URL** – Your Passportal instance domain (e.g., `mycompany.passportalmsp.com`).
2. **API Access Key ID** – Your Passportal API Access Key ID.
3. **HMAC Token** – A pre-generated HMAC-SHA256 hash token (base64 encoded).
Copy link
Contributor

Choose a reason for hiding this comment

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

[Documentation]

Factual inconsistency: Earlier steps create a hexadecimal HMAC hash, but this line says the token is base-64 encoded. Update to the correct encoding.

Context for Agents
[**Documentation**]

Factual inconsistency: Earlier steps create a hexadecimal HMAC hash, but this line says the token is base-64 encoded. Update to the correct encoding.

File: docs/integrations/all/passportal/connect.mdx
Line: 11

Copy link
Author

Choose a reason for hiding this comment

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

We say "hexadecimal" or "hex" now.

4. **Content String** – The plain text message used to compute the HMAC token.

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

Your base URL name is the domain in your Passportal URL:

- If your URL is `https://mycompany.passportalmsp.com/dashboard` → Your base URL is `mycompany.passportalmsp.com`
- If your URL is `https://instance.passportalmsp.com/dashboard` → Your instance is `instance.passportalmsp.com`
Copy link
Contributor

Choose a reason for hiding this comment

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

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
This will depend on the comment below.

Copy link
Author

Choose a reason for hiding this comment

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

Nice re-wording. This is indeed consistent with the correct, full-base-URL approach we need to take here. I have adopted the suggestion.


### 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" style={{maxWidth: "450px" }}/>
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
<img src="/integrations/all/passportal/passportal-settings.png" style={{maxWidth: "450px" }}/>
<img src="/integrations/all/passportal/passportal-settings.png"/>

same as the rest.

Copy link
Author

Choose a reason for hiding this comment

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

I've removed the style={{...}} attributes.

3. Click **Create access key**.
<img src="/integrations/all/passportal/passportal-api-keys.png" style={{maxWidth: "450px" }}/>
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" style={{maxWidth: "450px" }}/>
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" style={{maxWidth: "450px" }}/>
Copy link
Contributor

Choose a reason for hiding this comment

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

[Documentation]

Broken image path: File added is "passportal-api-keys.png" but the source here points to "api-keys.png". Update the filename or path so the image loads.

Context for Agents
[**Documentation**]

Broken image path: File added is "passportal-api-keys.png" but the source here points to "api-keys.png". Update the filename or path so the image loads.

File: docs/integrations/all/passportal/connect.mdx
Line: 40


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 **Instance Name**, **API Access Key ID**, **HMAC Token**, and **Content String**:
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn’t match the Connect UI form fields. To be determined based on the comment regarding base_url vs. subdomain.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you. This has been made consistent, including a consistent order between fields in the docs and fields in the connect modal form.

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

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.
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>
57 changes: 57 additions & 0 deletions packages/providers/providers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9187,6 +9187,63 @@ 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: data.expiry_time
Copy link
Contributor

@hassan254-prog hassan254-prog Oct 31, 2025

Choose a reason for hiding this comment

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

Suggested change
token_expiration: data.expiry_time
token_expiration: expiry_time

You can verify this by checking the Access Token Expiration under connection in the Nango dashboard. I would also check if the token refreshes when you manually refresh from nango ui.

Copy link
Author

Choose a reason for hiding this comment

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

Good catch. token_expiration: expiry_time is indeed correct.

Unfortunately I can't find a control in the Nango UI to manually refresh, but the expiry time does actually show up now.

Screenshot 2025-11-01 at 20 48 36

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 (generated in the dashboard under Administration > API)
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 (HMAC-SHA256 hash of your content string, hex encoded)
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 (e.g., 'api-content-hash')
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.