Embedding authentication

Embedding an authentication flow to your customers' systems in your app

Getting started

Polytomic Connect allows you to embed Polytomic's API in your own product, thus adding the ability to sync and ETL data between your customers' systems and your own.

As an alternative to building your own authentication flow, Polytomic Connect can handle all authentication to your customers' systems, whether to databases, data warehouses, CRMs, spreadsheets, or even arbitrary HTTP APIs. Through an API call to Polytomic Connect, you can present your users with Polytomic-provided authentication flows without worrying about building the right input form or OAuth flow.

For example, here are example modals generated by Polytomic Connect to authenticate to HubSpot and Snowflake:

Polytomic supports many other integrations. For each one, you're able to pop up authentication modals like the above without having to know what authentication parameters are required.

Code example

Below is an example of both frontend and backend code that authenticates to PostgreSQL using the Polytomic Connect API. Note that PostgreSQL can easily be replaced by any other integration; the caller does not need any knowledge of the required authentication inputs because that is automatically handled by Polytomic Connect.

📘

Authentication

Polytomic Connect requires an API key. If you haven't already, check out our Authentication documentation.

Requests should be proxied through a backend server so that the API token can be securely added to all outgoing requests. Demonstrated below are two parts broken up by frontend and backend

Frontend

const PROXY = "https://localhost:8081";
const REDIRECT_URL = "http://localhost:8080/connect_complete";

async function initiatePolytomicConnect() {
  const response = await fetch(`/_/api/connections/connect`, {
    method: "POST",
    mode: 'cors',
    cache: 'no-cache', 
    credentials: 'same-origin',
    body: JSON.stringify({
      type: "postgresql",
      name: "My Postgres connection",
      redirect_url: REDIRECT_URL,
    }),
  });
  if (response.ok) {
    const data = await response.json();
    window.open(data.data.redirect_url, "_blank")
    return;
  }
  const { error } = await response.json();
  throw new Error(error);
}

Backend

import requests

from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware


token = "YOUR-API-TOKEN"

app = FastAPI()
origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# Proxy requrest from frontend, inject token
@app.post("/_/api/connections/connect/")
async def connect(request: Request):
    body = await request.json()
    response = requests.post(
        url="https://app.polytomic.com/api/connections/connect/", 
        headers={
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
            "X-Polytomic-Version": "2023-04-25"
        },
        json=body,
    )

    return Response(
        content=response.content,
        status_code=response.status_code,
        headers=dict(response.headers),
    )
       

Note that you can provide Polytomic Connect with a specific list of connections that your user will be able to choose from. Here's a frontend example that will pop up a modal listing HubSpot, Marketo, Outreach, and Salesforce as connection options:

onst PROXY = "https://localhost:8081";
const REDIRECT_URL = "http://localhost:8080/connect_complete";

async function initiatePolytomicConnect() {
  const response = await fetch(`/_/api/connections/connect`, {
    method: "POST",
    mode: "cors",
    cache: "no-cache",
    credentials: "same-origin",
    body: JSON.stringify({
      whitelist: ["salesforce", "hubspot", "marketo", "outreach"],
      name: "Polytomic connection",
      redirect_url: REDIRECT_URL,
    }),
  });
  if (response.ok) {
    const data = await response.json();
    window.open(data.data.redirect_url, "_blank")
    return;
  }
  const { error } = await response.json();
  throw new Error(error);
}