Before getting started, you must have set up the auth flow through magic-link or using the embedded snippet. If you need to understand in depth these concepts, jump to the magic-link and frontend widget recipes.

You may need to follow first our webhook guide so you can understand quickly the next steps.

How to catch connection tokens ?

A connection_token is created everytime a user connects an account to your platform.
It is a field of the Connection Object that Panora sends as a payload data through a webhook when you listen to events tagged as connection.created.

1

Create a webhook endpoint handler to receive event data POST requests.

We must listen to connection.created event.

// This example uses Express to receive webhooks
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json());

// Match the raw body to content type application/json
// If you are using Express v4 - v4.16 you need to use body-parser, not express, to retrieve the request body
app.post('/webhook', (request, response) => {
    const event = request.body;

    // Handle the event
    switch (event.type) {
        case 'connection.created':
            const connectionObject = JSON.parse(event.data);
            // Then define and call a method to handle the successful connection creation.
            // handleConnectionCreationSucceeded(connectionObject);
            break;
        default:
            console.log(`Unhandled event type ${event.type}`);
    }

    // Return a response to acknowledge receipt of the event
    response.json('Received !');
});

app.listen(8000, () => console.log('Running on port 8000'));

If you log event.data, you’ll be able to check that it is a Connection Object. Hence, it contains an id_linked_user(more info here) which is helpful to attach it to your own end-user on your backend/db systems.

2

Register your endpoint within Panora using the Dashboard or the API.

Register the webhook endpoint’s accessible URL using the Webhooks section or the API so Panora knows where to deliver events.

Webhook URL format

The URL format to register a webhook endpoint is:

https://<your-website>/<your-webhook-endpoint>

For example, if your domain is https://mycompanysite.com and the route to your webhook endpoint is @app.route('/panora_webhooks', methods=['POST']), specify https://mycompanysite.com/panora_webhooks as the Endpoint URL.

Add a webhook endpoint

Navigate to the Configuration section and head to the Webhooks tab.

Register a webhook endpoint with the Panora API

You can also programmatically create webhook endpoints.

The following example creates an endpoint that notifies you when a connection is created.

curl --request POST \
     --url https://api.panora.dev/webhooks \
     --header 'x-api-key: <api-key>' \
     --header 'Content-Type: application/json' \
     --data '{
        "url": "https://acme.com/webhook_receiver",
        "description": "Receive Connection Creation Events",
        "scope": [
            "connection.created"
        ]
     }'
3

Secure your webhook endpoint.

We highly recommend you secure your integration by ensuring your handler verifies that all webhook requests are generated by Panora. You can choose to verify webhook signatures using our official libraries or verify them manually.

Verify webhook signatures with official library

We recommend using our official libraries to verify signatures. You perform the verification by providing the event payload, the Panora-Signature header, and the endpoint’s secret. If verification fails, you get an error.

import express, { Request, Response } from 'express';
import { Panora } from '@panora/sdk';

type ConnectionData = {
    connection_token: string;
    provider_slug: string;
    vertical: string;
    [key: string]: any;
}

// Set your api key
// See your keys here: https://app.panora.dev/api-keys
const panora = new Panora({ apiKey: process.env.API_KEY });

// Find your endpoint's secret in your webhook settings in the Config Page
const endpointSecret = 'whsec_...';

// This example uses Express to receive webhooks
const app = express();

app.use(express.json());

// Match the raw body to content type application/json
app.post('/webhook', async (request, response) => {
    const sig = request.headers['panora-signature'];

    let event: Record<string, any> = {};

    try {
        // Verifies that the event comes from Panora and not from malicious sender
        event = await panora.webhooks.verifyEvent({
            payload: request.body,
            signature: sig as any,
            secret: endpointSecret,
        });
    }
    catch (err) {
        response.status(400).send(`Webhook Error: ${(err as any).message}`);
    }

    // Handle the event
    switch (event.type) {
        case 'connection.created':
            const connectionData: ConnectionData = JSON.parse(event.data);
            console.log(`Received connectionToken data ${JSON.stringify(connectionData)}`)
            break;
        case 'filestorage.file.pulled':
            console.log(`Retrieving files...`)
            const files = event.data;
            console.log(JSON.stringify(files))
            /*Alternatively you can use our SDK with your connectionToken to retireve the same data
            
            const result = await panora.filestorage.files.list({
                xConnectionToken: connectionToken,
                remoteData: true,
            });
            for await (const page of result) {
                console.log(`Files are ${JSON.stringify(page.result)}`)
            }*/
            break;
        default:
            console.log(`Unhandled event type ${event.type}`);
    }
    // Return a response to acknowledge receipt of the event
    response.json('Received !');

});

app.listen(8080, () => console.log('Running on port 8080'));