Skip to main content
Not an official partner? If you are not an official Filed partner and want to integrate as a customer, please use the Customer integration guide instead.
This guide walks you through the complete partner integration process, from receiving your API key to generating deep links for your customers. Follow these steps to start onboarding tax firms to Filed.
Important: Each partner manages multiple customers (tax firms). Each workspace represents one customer/tax firm. You’ll create a separate workspace for each tax firm customer you onboard.

Prerequisites

Before you begin, ensure you have:
  • Partner account with Filed
  • API access credentials (API Key)
  • Partner key (provider or partner key is a unique identifier from Filed for your platform)
  • Dedicated slack channel for your partner account
  • GraphQL endpoint: https://gateway.filed.com/graphql
Contact your Filed account representative if you need assistance creating your partner account, API key, and partner key or have questions about the integration process.

Overview

The partner integration process enables you to:
  1. Authenticate to Filed’s API using your API key
  2. Verify your connection by testing the API key with a sample query
  3. Create workspaces for each customer (tax firm) - one workspace per tax firm
  4. Onboard tax firm users by adding them to their respective workspaces
  5. Set up integrations with tax software providers for each tax firm
  6. Generate deep links that seamlessly redirect tax firm users to Filed

Understanding the model

  • Partner: Your partner user account that manages multiple tax firm customers
  • Workspace: Each workspace represents one customer (tax firm)
    • One workspace = One customer = One tax firm
    • A workspace can have multiple users from the same tax firm
    • Partners like you can create multiple workspaces (one for each tax firm customer)

Integration Workflow

The partner integration process consists of six main steps:

Step 1: Authenticate to Filed’s API using your API key

Exchange your API key for an access token that will be used for all subsequent API requests.

GraphQL mutation

mutation LoginViaPersonalApiToken($apiKey: String!) {
  loginViaPersonalApiToken(token: $apiKey) {
    accessToken
  }
}

Implementation notes

  • Store the accessToken securely and use it in the Authorization header for all subsequent requests
  • Access tokens are valid for a limited time; implement token refresh logic as needed
  • Format: Authorization: Bearer <accessToken>
  • Include a source-platform header with your partner name or identifier (e.g., <partner_key>, qount, partner-name). This header is used to uniquely identify API requests for analytical purposes and does not affect rate limits or any other API functionality.
Important: The access token obtained from your partner API key provides access to all workspaces you create as a partner. This means you can use the same access token to call APIs against any workspace you’ve created, allowing you to manage multiple tax firm customers from a single authenticated session.
Security Best Practice: Store your API key securely and never commit it to version control. Use environment variables or secure secret management tools.

Step 2: Verify your connection

Make a test request to verify your API key works correctly. The me query returns information about the authenticated user.

GraphQL Query

query Me {
  me {
    id
    name
  }
}

Implementation notes

  • The me query returns information about the currently authenticated user
  • A successful response confirms your API integration is working correctly
  • The id field uniquely identifies the authenticated user
Success! If you receive a valid response with your user information, your API key is working correctly and you’re ready to proceed with creating workspaces.

Step 3: Create workspace for each customer (tax firm)

Create a workspace for each tax firm customer. Each workspace represents one tax firm and will be used to manage that tax firm’s users and their tax preparations.
Note: You’ll create a separate workspace for each tax firm customer. If you have 10 tax firm customers, you’ll create 10 workspaces.

GraphQL mutation

mutation CreateWorkspace($input: CreateWorkspaceInput!) {
  createWorkspace(input: $input) {
    id
    slug
    displayName
    status
    workspaceType
  }
}

Implementation notes

  • Save the workspaceId and slug for each workspace (customer) - you’ll need the workspace ID for adding users and the slug for generating deep links
  • The slug is essential for creating reliable deep links that route customers to the correct workspace
  • Workspace type will be automatically set to partner for partner accounts
  • Create a new workspace for each tax firm customer you onboard
  • Store the mapping between your customer IDs, workspace IDs, and workspace slugs for reference

Step 4: Add tax firm users to workspace

Add the tax firm’s users (preparers, staff, etc.) to their workspace by email addresses. This enables them to access Filed through deep links.

GraphQL mutation

mutation AddUsersToWorkspace($workspaceId: ID!, $userEmails: [String!]!) {
  addUsersToTheWorkspace(workspaceId: $workspaceId, userEmails: $userEmails) {
    id
    email
    name
    role
  }
}

Implementation notes

  • No email invitations are sent - users are simply added to the workspace
  • If a user already exists, they will be added to the workspace without creating a duplicate account
  • You can add multiple users in a single request
  • Add users to the specific workspace that corresponds to their tax firm
  • After being added, users can sign in using their email address and access the workspace through deep links

Step 5: Set up your integration with Filed

Complete the integration setup between your platform and Filed by establishing a provider connection. This enables Filed to communicate with your platform using the credentials and configuration you provide.
Implementation Details: The specific implementation of what happens on Filed’s side when startProviderConnection and verifyProviderConnection are called will be discussed and coordinated between your team and Filed’s engineering team during the integration process.
The integration process consists of two steps:
  1. Start Provider Connection: This is used to setup a connection between your platform and Filed. You can pass in credentials for the specific tax firm based on what our engineering teams agree on. The idea is after you call this, in Filed’s integration section, the integration with your name on it will start showing up as pending.
  2. Verify Provider Connection: This is where Filed will use the credentials and details you provided and call an endpoint at your end to test the connection between you and us. If this call succeeds, we will now start showing on our end that Filed and your platform has successfully connected. You can now start using the connection ID (the id field from the response) to send the tax prep to us.

Step 5a: Start Provider Connection

This is used to setup a connection between your platform and Filed. You can pass in credentials for the specific tax firm based on what our engineering teams agree on. The idea is after you call this, in Filed’s integration section, the integration with your name on it will start showing up as pending.
For complete API reference, see Start provider connection.
Partner Key: Filed will provide you with a unique partner key identifier for your platform. Examples:
  • If Google was our partner we would use: google
  • Your specific partner key will be provided by Filed during partner onboarding
GraphQL mutation
mutation StartProviderConnection($workspaceId: ID!, $providerKey: String!, $inputs: JSON) {
  startProviderConnection(workspaceId: $workspaceId, providerKey: $providerKey, inputs: $inputs) {
    id
    workspaceId
    providerKey
    status
    action
    displayName
    createdAt
  }
}
Implementation notes
  • workspaceId: The ID of the workspace (tax firm) you’re setting up the integration for
  • providerKey: Your partner key provided by Filed (e.g., <partner_key>, qount)
  • inputs: Optional JSON object containing firm-specific credentials and configuration:
    • apiKey: Firm’s API key for your platform
    • securityToken: Security token or authentication token
    • baseUrl: Base URL for API calls (if different from default)
    • Any other credentials or configuration your platform requires
  • Save the id from the response - you’ll need it for the collect step
  • The connection status will be pending until you complete the collect step

Step 5b: Verify Provider Connection

This is where Filed will use the credentials and details you provided and call an endpoint at your end to test the connection between you and us. If this call succeeds, we will now start showing on our end that Filed and your platform has successfully connected. You can now start using the connectionId to send the tax prep to us.
For complete API reference, see Verify provider connection.
Deprecated: The collectProviderConnection mutation is deprecated but will continue to work. It’s recommended to use verifyProviderConnection instead, as it’s the preferred method going forward.
GraphQL mutation
mutation VerifyProviderConnection($connectionId: ID!, $inputs: JSON) {
  verifyProviderConnection(connectionId: $connectionId, inputs: $inputs) {
    id
    workspaceId
    providerKey
    status
    displayName
    settings
    updatedAt
  }
}
Implementation notes
  • connectionId: The connection ID (the id field) returned from the startProviderConnection mutation
  • inputs: Optional JSON object containing additional configuration:
    • firmReferenceId: Your internal reference ID for the tax firm (useful for correlation)
    • Any other parameters you want Filed to store for this tax firm
    • Configuration that helps Filed communicate with your platform
  • Filed will use the credentials from the start step to make an API call to your platform
  • If the API call succeeds, Filed marks the connection as active
  • If the API call fails, the connection status will reflect the error state
Connection Status: After successful collection, the connection status will be active, indicating that Filed can successfully communicate with your platform using the provided credentials.
Security: Ensure that the credentials you provide in the startProviderConnection mutation are valid and have the necessary permissions for Filed to make API calls to your platform on behalf of the tax firm.

Generate deep links that seamlessly redirect tax firm users to Filed. These links can be used at any time to send users from a specific tax firm to their workspace and specific pages within Filed.
Important: Always use the workspace slug format (/w/{workspaceSlug}/) when available to ensure customers are directed to the correct workspace. This prevents routing errors and ensures proper workspace isolation.
For detailed information about deep link formats, common redirect paths, and implementation examples, see the Deep links API reference.

Complete Integration Example

Here’s a complete example showing all steps together:
const GRAPHQL_ENDPOINT = 'https://gateway.filed.com/graphql';

// Step 1: Authenticate
const authResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
    query: `
      mutation LoginViaPersonalApiToken($token: String!) {
        loginViaPersonalApiToken(token: $token) {
          accessToken
        }
      }
    `,
    variables: { token: process.env.FILED_API_TOKEN }
  })
});

const { accessToken } = (await authResponse.json()).data.loginViaPersonalApiToken;

// Step 2: Verify Connection
const meResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
      query: `
        query Me {
          me {
            id
            name
          }
        }
      `
  })
});

const { data: meData } = await meResponse.json();
console.log('✓ API key verified. Current user:', meData.me);

// Step 3: Create Workspace
const workspaceResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
    query: `
      mutation CreateWorkspace($input: CreateWorkspaceInput!) {
        createWorkspace(input: $input) {
          id
          slug
          displayName
        }
      }
    `,
    variables: {
      input: {
        displayName: 'Smith & Associates Tax Firm',
        firmSize: 'md',
        metadata: {
          customerId: 'customer-123'
        }
      }
    }
  })
});

const { id: workspaceId, slug: workspaceSlug } = 
  (await workspaceResponse.json()).data.createWorkspace;

// Step 4: Add Tax Firm Users
const addUsersResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
    query: `
      mutation AddUsersToWorkspace($workspaceId: ID!, $userEmails: [String!]!) {
        addUsersToTheWorkspace(workspaceId: $workspaceId, userEmails: $userEmails) {
          id
          email
        }
      }
    `,
    variables: {
      workspaceId,
      userEmails: ['[email protected]', '[email protected]']
    }
  })
});

// Step 5a: Start Provider Connection
const startConnectionResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
    query: `
      mutation StartProviderConnection($workspaceId: ID!, $providerKey: String!, $inputs: JSON) {
        startProviderConnection(workspaceId: $workspaceId, providerKey: $providerKey, inputs: $inputs) {
          id
          status
        }
      }
    `,
    variables: {
      workspaceId,
      providerKey: '<partner_key>', // Your partner key
      inputs: {
        apiKey: 'firm-specific-api-key-12345',
        securityToken: 'firm-security-token-abc'
      }
    }
  })
});

const { id: connectionId } = (await startConnectionResponse.json()).data.startProviderConnection;

// Step 5b: Verify Provider Connection
const verifyConnectionResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': '<partner_key>'
  },
  body: JSON.stringify({
    query: `
      mutation VerifyProviderConnection($connectionId: ID!, $inputs: JSON) {
        verifyProviderConnection(connectionId: $connectionId, inputs: $inputs) {
          id
          status
        }
      }
    `,
    variables: {
      connectionId,
      inputs: {
        firmReferenceId: 'firm-ref-12345'
      }
    }
  })
});

const { status: connectionStatus } = (await verifyConnectionResponse.json()).data.verifyProviderConnection;
console.log(`✓ Integration connection status: ${connectionStatus}`);

// Step 6: Generate Magic Link (using workspace slug - recommended)
const magicLink = `https://app.filed.com/sign-in?deep_link=/w/${workspaceSlug}`;
console.log('Send this link to the tax firm users:', magicLink);

Best Practices

Security

  1. Never expose API keys: Store API keys in environment variables or secure secret management systems
  2. Use HTTPS: Always make API requests over HTTPS
  3. Validate inputs: Always validate user inputs before making API calls

Error handling

  1. Handle authentication errors: Implement retry logic for expired tokens
  2. Validate responses: Check for errors in GraphQL responses
  3. Log errors: Maintain error logs for debugging and monitoring

User experience

  1. Provide clear instructions: Guide tax firm users on what to expect when clicking deep links
  2. Handle edge cases: Account for users who may already have Filed accounts
  3. Monitor onboarding: Track tax firm user activation rates and identify bottlenecks
  4. Workspace isolation: Ensure users from different tax firms are directed to their correct workspaces

Support

For additional support or questions:
  • Slack: Contact your dedicated partner Slack channel
  • Email: Reach out to your Filed account representative
  • Documentation: Check our API documentation for more details

Next Steps

After completing the integration:
  1. Review API reference: Check out the detailed API reference for complete endpoint documentation
  2. Test the flow: Create a test workspace for a tax firm customer and verify all steps work correctly
  3. Monitor usage: Track API usage and tax firm onboarding metrics per workspace
  4. Iterate: Gather feedback and refine your integration based on tax firm needs
  5. Scale: Automate the process to handle multiple tax firm customers efficiently
  6. Manage multiple workspaces: Implement systems to track and manage workspaces for all your tax firm customers