Skip to content
Last updated: 2026-04-06
Reference

API Integration Guide

Dxtra provides GraphQL and REST APIs for privacy compliance integration. No proprietary SDKs are required -- use standard GraphQL clients in your preferred language.

Integration Approach

Dxtra uses a GraphQL-first API architecture. Use any standard GraphQL client library (Apollo, graphql-request, gql, etc.) in your preferred language.

Integration Methods

GraphQL API (Primary)

Direct access to Dxtra's privacy data using GraphQL.

API Endpoint:

Environment GraphQL API Authentication
Production https://api.dxtra.ai/v1/graphql https://auth.dxtra.ai

Implementation Pattern:

JavaScript
// Use any GraphQL client -- Apollo Client, urql, graphql-request, etc.
import { GraphQLClient } from 'graphql-request';

// 1. Authenticate to get JWT token
const authResponse = await fetch('https://auth.dxtra.ai/v1/signin/pat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ personalAccessToken: process.env.DXTRA_PAT })
});

const { session } = await authResponse.json();
const jwtToken = session.accessToken;

// 2. Create GraphQL client with JWT
const client = new GraphQLClient('https://api.dxtra.ai/v1/graphql', {
  headers: {
    'Authorization': `Bearer ${jwtToken}`,
    'X-Hasura-Role': 'user'
  }
});

// 3. Execute queries
const data = await client.request(`
  query GetDataSubjects($controllerId: uuid!) {
    dataSubjects(where: {dataControllerId: {_eq: $controllerId}}) {
      id
      did
      createdAt
    }
  }
`, { controllerId: 'your-controller-id' });

REST API

Selected GraphQL operations exposed as REST endpoints for simple HTTP access.

Bash
# Get data controller details
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
     -H "X-Hasura-Role: user" \
     "https://api.dxtra.ai/api/rest/getdatacontrollerdetails"

# Submit rights request
curl -X POST \
     -H "Authorization: Bearer YOUR_JWT_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"dataSubjectId": "uuid", "requestType": "access"}' \
     "https://api.dxtra.ai/api/rest/insertdatasubjectsrightsrequest"

REST vs GraphQL

REST endpoints are simpler for basic operations but less flexible than GraphQL. Use REST for quick prototypes, GraphQL for production applications requiring complex data access.

Webhook Integration

Configure third-party services to send data to Dxtra via webhooks.

Webhook URL Pattern:

Text Only
https://conduit.dxtra.ai/api/v1/integrations/{service}/event?did={YOUR_DID}&dxKey={YOUR_DX_KEY}

Legacy vs. current authentication

The ?did=...&dxKey=... query parameter format applies to Shopify and legacy integrations. Newer integrations (Stripe, Xero, Salesforce) use a JWE token format instead: ?token={JWE_TOKEN}. See the integration-specific guides for the correct format.

See the Webhook Guide for platform-specific configuration.

Transparency Center (Web Component)

Embed the Transparency Center on your website as a custom element:

HTML
<!-- Load the Transparency Center -->
<script src="https://transparencycenter.dxtra.ai/assets/index.js" type="module"></script>

<!-- Embed the privacy portal -->
<transparency-app data-controller-id="YOUR_DATA_CONTROLLER_ID"></transparency-app>

The Transparency Center provides a self-service privacy portal where data subjects can:

  • View processing purposes and legal basis
  • Submit rights requests (access, deletion, portability)
  • Manage consent preferences
  • Access privacy notices and FAQs

See Transparency Center for configuration details.

Language-Specific Examples

Node.js / TypeScript

Recommended Libraries:

Bash
npm install graphql-request graphql

Implementation:

TypeScript
import { GraphQLClient } from 'graphql-request';

interface AuthSession {
  session: {
    accessToken: string;
    refreshToken: string;
    accessTokenExpiresIn: number;
  };
}

class DXTRAClient {
  private client: GraphQLClient;
  private pat: string;
  private accessToken: string | null = null;
  private tokenExpiry: number = 0;

  constructor(personalAccessToken: string) {
    this.pat = personalAccessToken;
    this.client = new GraphQLClient('https://api.dxtra.ai/v1/graphql');
  }

  private async refreshToken(): Promise<void> {
    const response = await fetch('https://auth.dxtra.ai/v1/signin/pat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ personalAccessToken: this.pat })
    });

    if (!response.ok) {
      throw new Error(`Authentication failed: ${response.statusText}`);
    }

    const data: AuthSession = await response.json();
    this.accessToken = data.session.accessToken;
    this.tokenExpiry = Date.now() + (data.session.accessTokenExpiresIn - 120) * 1000;

    this.client.setHeaders({
      'Authorization': `Bearer ${this.accessToken}`,
      'X-Hasura-Role': 'user'
    });
  }

  async query<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
    if (!this.accessToken || Date.now() >= this.tokenExpiry) {
      await this.refreshToken();
    }
    return this.client.request<T>(query, variables);
  }
}

// Usage
const client = new DXTRAClient(process.env.DXTRA_PAT!);
const data = await client.query(`
  query GetDataControllers {
    dataControllers { id title did }
  }
`);

Python

Recommended Libraries:

Bash
pip install gql[all]

Implementation:

Python
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
import requests
import os
from datetime import datetime, timedelta

class DXTRAClient:
    def __init__(self, personal_access_token: str):
        self.pat = personal_access_token
        self.access_token = None
        self.token_expiry = None
        self.client = None

    def _refresh_token(self):
        response = requests.post(
            'https://auth.dxtra.ai/v1/signin/pat',
            json={'personalAccessToken': self.pat}
        )
        response.raise_for_status()

        data = response.json()
        self.access_token = data['session']['accessToken']
        expires_in = data['session']['accessTokenExpiresIn'] - 120
        self.token_expiry = datetime.now() + timedelta(seconds=expires_in)

        transport = RequestsHTTPTransport(
            url='https://api.dxtra.ai/v1/graphql',
            headers={
                'Authorization': f'Bearer {self.access_token}',
                'X-Hasura-Role': 'user'
            }
        )
        self.client = Client(transport=transport, fetch_schema_from_transport=True)

    def query(self, query_string: str, variables: dict = None):
        if not self.access_token or datetime.now() >= self.token_expiry:
            self._refresh_token()

        query = gql(query_string)
        return self.client.execute(query, variable_values=variables)

# Usage
client = DXTRAClient(os.getenv('DXTRA_PAT'))
result = client.query("""
    query GetDataControllers {
        dataControllers { id title did }
    }
""")

React Applications

Recommended Libraries:

Bash
npm install @nhost/react @nhost/react-apollo graphql

Implementation:

TypeScript
import { NhostClient, NhostProvider, useAuthenticated, useNhostClient } from '@nhost/react';
import { NhostApolloProvider } from '@nhost/react-apollo';
import { useEffect } from 'react';

// Initialize Nhost client with custom domain
const nhost = new NhostClient({
  authUrl: 'https://auth.dxtra.ai',
  graphqlUrl: 'https://api.dxtra.ai/v1/graphql',
  storageUrl: 'https://storage.dxtra.ai',
});

function App() {
  return (
    <NhostProvider nhost={nhost}>
      <NhostApolloProvider nhost={nhost}>
        <AuthenticatedApp />
      </NhostApolloProvider>
    </NhostProvider>
  );
}

function AuthenticatedApp() {
  const isAuthenticated = useAuthenticated();
  const nhost = useNhostClient();

  // Authenticate with PAT via direct HTTP exchange
  useEffect(() => {
    if (!isAuthenticated) {
      // PATs are exchanged via POST to /v1/signin/pat
      fetch(`${nhost.auth.url}/v1/signin/pat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          personalAccessToken: process.env.REACT_APP_DXTRA_PAT
        })
      })
        .then(res => res.json())
        .then(data => {
          // Use the returned session to authenticate the Nhost client
          if (data.session) {
            nhost.auth.setSession(data.session);
          }
        });
    }
  }, [isAuthenticated, nhost]);

  if (!isAuthenticated) {
    return <div>Authenticating...</div>;
  }

  return <Dashboard />;
}

// Use Apollo Client hooks for queries
import { useQuery, gql } from '@apollo/client';

const GET_DATA_CONTROLLERS = gql`
  query GetDataControllers {
    dataControllers { id title did }
  }
`;

function Dashboard() {
  const { data, loading, error } = useQuery(GET_DATA_CONTROLLERS);
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (
    <ul>
      {data.dataControllers.map((controller: any) => (
        <li key={controller.id}>{controller.title}</li>
      ))}
    </ul>
  );
}

Response Format

Dxtra's GraphQL API returns standard GraphQL response shapes:

  • Success: { "data": { ... } }
  • Error: { "errors": [{ "message": "...", "extensions": { ... } }] }

Authentication

Dxtra uses a two-step authentication flow:

  1. Exchange Personal Access Token (PAT) for JWT
  2. Use JWT for API requests (valid 1 hour)
  3. Refresh JWT before expiration or on 401 errors

See the Authentication Guide for detailed implementation patterns.

Best Practices

Query Optimization

GraphQL
# Request only needed fields
query GetDataSubjects {
  dataSubjects(limit: 50) {
    id
    did
    createdAt
  }
}

Error Handling

TypeScript
async function safeQuery<T>(client: DXTRAClient, query: string): Promise<T | null> {
  try {
    return await client.query<T>(query);
  } catch (error) {
    if (error.response?.status === 401) {
      console.log('Token expired, retrying with fresh token');
      return await client.query<T>(query);
    }
    if (error.response?.status === 429) {
      console.error('Rate limit exceeded');
      throw new Error('Rate limit exceeded. Please retry later.');
    }
    console.error('Query failed:', error);
    return null;
  }
}

Security

  • Store PATs securely -- Use environment variables, never commit to source control
  • Use HTTPS only -- All API calls must use encrypted connections
  • Rotate credentials -- Change PATs regularly
  • Validate input -- Sanitize all variables before passing to queries
  • Respect rate limits -- Implement retry logic with exponential backoff

Next Steps

For integration questions, email privacy@dxtra.ai.