What’s Supabase?

Supabase is an open source Firebase alternative providing all the backend features you need to build a product. This includes a Postgres database, authentication, instant APIs, edge functions, realtime subscriptions, and more.

With Sequin, you can stream data from APIs like Salesforce, GitHub, and Stripe directly into Supabase Postgres tables. This means you can query your API data using Supabase’s powerful SQL interface, and join it with other data sources in your Supabase database.

To stream data to Supabase Postgres via Sequin, you will:

  • Create a Supabase project and Postgres database
  • Create a table in the public schema for Sequin
  • Create a Postgres user for Sequin
  • Connect Sequin to an API source
  • Create a Sequin Postgres consumer that streams to Supabase

Sequin will first copy all historical data from the API into your Supabase Postgres database, then will keep the database up-to-date by inserting, updating, or deleting rows as changes occur in the API. This means your Supabase database will always be in sync with your API data.

Create a Supabase project and Postgres database

Sign up for a Supabase account at https://app.supabase.com/.

Once logged in, create a new project. Supabase will provision a Postgres database for you.

Create a table in the public schema for Sequin

Next, create a table in your Supabase database for Sequin to sync API data to. We recommend creating this table in the public schema, as it works best with Supabase’s built-in features like realtime subscriptions and Row Level Security (RLS).

Navigate to the “SQL Editor” in the Supabase dashboard.

Create a table for Sequin to sync API data to:

create table public.sequin_records (
  sequin_id uuid not null,
  sync_id uuid not null,
  collection_id text not null,
  upstream_id text not null,
  payload jsonb not null,
  upstream_updated_at timestamp with time zone not null,
  upstream_created_at timestamp with time zone,
  inserted_at timestamp with time zone not null,
  updated_at timestamp with time zone not null,
  primary key (sequin_id)
);

This table will store API data from all collections, with the actual payload stored in the payload JSONB column. You’ll see later how to create views on top of this table to flatten the JSON payload into a tabular format.

Create a Postgres user for Sequin

Create a dedicated Postgres user for Sequin with permissions to read and write to the public.sequin_records table.

In the “SQL Editor,” run:

create user sequin with password 'generate-a-strong-password-here';

Then, grant the sequin user the necessary privileges:

grant usage on schema public to sequin;
grant select, insert, update, delete on public.sequin_records to sequin;

These statements grant the sequin user permissions to read and write to the public.sequin_records table.

Configure Row Level Security (RLS)

By default, Supabase enables Row Level Security (RLS) on all tables in the public schema. This means that each user can only access rows that they have permissions for, based on policies you define.

For the public.sequin_records table, we want to allow the sequin user to access all rows, while restricting access for other users based on your application’s needs.

To allow the sequin user full access, create a policy:

create policy sequin_user_all
on public.sequin_records
for all
to sequin
using (true);

This policy allows the sequin user to perform all operations (select, insert, update, delete) on all rows in the public.sequin_records table.

For other users, you can define policies based on your specific requirements. For example, to allow all authenticated users read access:

create policy authenticated_users_select
on public.sequin_records
for select
to authenticated
using (true);

You can define more granular policies as needed. Refer to the Supabase RLS docs for more details.

Connect Sequin to an API source

You can connect Sequin to an upstream API using either the Sequin console or API.

Here’s a curl request that connects Sequin to Salesforce:

curl --request POST \
  --url https://api.sequin.io/v1/syncs \
  --header 'Authorization: Bearer {your-api-token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "provider": "salesforce",
    "name": "Acme Corp - Salesforce Production",
    "collection_ids": ["salesforce:account", "salesforce:contact", "salesforce:opportunity"],
    "credential": {
      "properties": {
        "kind": "salesforce_oauth2",
        "secret": "{your-salesforce-oauth2-secret}",
        "name": "Salesforce prod"
      },
      "oauth_app_id": "{your-sequin-salesforce-oauth-app-id}",
    }
  }'

This request instructs Sequin to sync Salesforce accounts, contacts, and opportunities using the provided OAuth credentials.

Create a Sequin Postgres consumer

Next, create a Sequin Postgres consumer to stream data from Salesforce into your Supabase Postgres database.

You can create consumers in Sequin’s console or API. Here’s an example curl request:

curl --request POST \
  --url https://api.sequin.io/v1/postgres_consumers \
  --header 'Authorization: Bearer {your-api-token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Supabase - Salesforce",
    "schema": "public",
    "table": "sequin_records",
    "postgres": {
      "name": "supabase_prod",
      "connection": {
        "host": "db.abcdefghijklmnop.supabase.co",
        "port": 5432,
        "database": "postgres",
        "username": "sequin",
        "password": "{the-password-you-created-for-the-sequin-user}"
      }
    },
    "sync_id": "845e7d90-0d56-4f97-aa6a-af4abf06c4d7"
  }'

Use the connection details for your Supabase database’s host, port, and database. Use the sequin Postgres you created earlier for the username, and password fields.

The sync_id field specifies which Sequin sync to consume data from. Omit this field to consume data from all syncs.

At this point, your Salesforce data should be flowing into Supabase Postgres! Let’s verify by querying the database.

Query your API data in Supabase

Navigate to the SQL Editor in the Supabase dashboard.

To see how many records Sequin has synced:

select count(*) from public.sequin_records;

To view an example record:

select * from public.sequin_records limit 1;

You’ll see that the API payload is stored in the payload column as JSONB.

Now, any time an account, contact, or opportunity is created, updated, or deleted in Salesforce, Sequin will upsert a row in the public.sequin_records table in real-time!

Create views to flatten the JSON payload

While you can query the public.sequin_records table directly, it’s often more convenient to create views that flatten the nested JSON payload into a tabular format.

For example, here’s how you could create a view for Salesforce contacts:

create view public.salesforce_contacts as
select
    payload->>'Id' as salesforce_id,
    payload->>'AccountId' as account_id,
    payload->>'FirstName' as first_name,
    payload->>'LastName' as last_name,
    payload->>'Email' as email,
    payload->>'Phone' as phone,
    (payload->>'CreatedDate')::timestamp as created_at,
    (payload->>'LastModifiedDate')::timestamp as updated_at
from public.sequin_records
where collection_id = 'salesforce:contact';

The payload->> syntax extracts a value from the JSONB payload. The where collection_id clause is used to filter the view to only contacts.

With this approach, you can create a view for each collection you’re syncing from Salesforce. This gives you full control of the schemas for your API data. Because Sequin is syncing to the core public.sequin_records table, it will be unaffected by your schema changes.

With these views in place, you can now query your Salesforce data in Supabase just like any other Postgres table:

select
    c.first_name,
    c.last_name,
    c.email,
    a.name as account_name
from public.salesforce_contacts c
join public.salesforce_accounts a on c.account_id = a.salesforce_id
where c.updated_at > now() - interval '1 week';

To generate these views, you can use this handy tool.

Where to next?

With your API data streaming into Supabase Postgres, you can now build on your API data with all the speed and ease of Supabase.

If you weren’t following along, head over to Supabase to sign up for an account and start streaming.

Check out the Supabase docs to learn more about their platform, and the Sequin docs for more on streaming API data.