Skip to main content
This guide covers two integration patterns for creating tax preparations in Filed: pushing clients from your platform to Filed, and allowing Filed to pull clients from your platform.
Integration Pattern Selection: Choose the pattern that best fits your workflow. Pushing clients gives you full control over when and what data is sent. Pulling allows Filed to discover and fetch clients on-demand.

Prerequisites

Before you begin, ensure you have:
Integration Pattern Availability:
If you haven’t set up your provider connection yet, follow the partner integration guide to complete the connection setup first.

Overview

There are two ways to create tax preparations in Filed:
  1. Push clients to Filed: You control when and what data is sent to Filed
    • Create a connection job to batch process clients
    • Attach clients (works) to the job
    • Attach files (artifacts) to each client
    • Trigger the import to process all clients
  2. Filed pulls clients: Filed discovers and fetches clients from your platform
    • Filed queries your platform for clients
    • Filed queries files for each client
    • Filed downloads files as needed
    • Filed can upload files back to clients

Integration Pattern 1: Pushing Clients to Filed

This pattern gives you full control over when and what data is sent to Filed. You create connection jobs, attach clients and files, then trigger the import.

Step 1: Create connection job

Create an import job that groups related tax preparations together. A connection job can be triggered to process all attached clients.
For complete API reference, see Create connection job.

GraphQL mutation

mutation CreateConnectionJob($connectionId: ID!, $jobName: String!) {
  createConnectionJob(connectionId: $connectionId, jobName: $jobName) {
    id
    connectionId
    workspaceId
    name
    status
    createdAt
  }
}

Implementation notes

  • Save the id from the response - you’ll need it for creating works
  • Use descriptive job names to identify batches (e.g., “2024 Tax Season Import”, “Q1 Client Batch”)
  • Connection jobs group related tax preparations together for batch processing

Step 2: Create works (attach clients)

Attach clients to the connection job. Each work represents a tax preparation for a specific client.
For complete API reference, see Create job works.

GraphQL mutation

mutation CreateJobWorks($connectionJobId: ID!, $inputs: [CreateJobWorksInput!]!) {
  createJobWorks(connectionJobId: $connectionJobId, inputs: $inputs) {
    id
    createdAt
    updatedAt
    workspaceId
    workId
    connectionJobId
  }
}

Implementation notes

  • Save the id for each job work - you’ll need it for attaching files
  • Save the workId to reference the underlying work
  • The externalId in the input should match your platform’s client identifier for correlation
  • You can create multiple job works in a single request
  • Use descriptive names that identify the client and tax year

Step 3: Create work artifacts (attach files)

Attach files to each work. Artifacts represent documents, forms, or other files associated with a tax preparation. Before creating artifacts, you must first upload files to Filed’s upload endpoint.
For complete API reference, see Create job work artifacts.

Step 3a: Upload file to Filed

First, upload your file to Filed’s upload endpoint. This returns a fileUrl that you’ll use when creating the artifact. You can upload files using either multipart/form-data or by providing a URL.
Important: Partners and customers use different upload endpoints. Make sure you’re using the correct endpoint for your integration type.
Partners: Scroll down to the “FOR PARTNERS: Partner Upload Endpoint” section below. You must use the Partner Upload endpoint (https://partner-upload.filed.com/upload) - do NOT use the upload-proxy endpoint shown in the examples below.
Customers: The examples below use the upload-proxy endpoint which is for customers. Partners have a separate endpoint - see the Partner Upload section below.
Option 1: Upload file using multipart/form-data
curl --request POST \
  --url https://upload-proxy.filed.com/upload \
  --header 'Content-Type: multipart/form-data' \
  --form file=@/path/to/your/file.pdf \
  --form 'fileName=Phil Ed 2024 Return.PDF'
Option 2: Upload file using URL
You can upload files by providing a URL to the file. The mimeType parameter is optional.
curl --request POST \
  --url https://upload-proxy.filed.com/upload \
  --header 'Content-Type: multipart/form-data' \
  --form 'fileName=document.pdf' \
  --form 'url=https://example.com/file.pdf' \
  --form 'mimeType=application/pdf'
URL Upload: When uploading via URL, the mimeType parameter is optional. If not provided, Filed will attempt to detect the MIME type from the file URL or file content.

FOR PARTNERS: Partner Upload Endpoint (Required)
Partners Must Use This Endpoint: If you’re integrating as a partner, you must use the Partner Upload endpoint (https://partner-upload.filed.com/upload). Do NOT use the upload-proxy endpoint shown below. The Partner Upload endpoint is specifically designed for partner integrations and uses your partner JWT token for authentication.
Endpoint: https://partner-upload.filed.com/upload Authentication: Use your partner JWT token (not your access token) Upload file directly:
curl -X POST \
  -H "Authorization: Bearer <your-partner-jwt-token>" \
  -F "file=@./document.pdf" \
  -F "fileName=document.pdf" \
  -F "mimeType=application/pdf" \
  https://partner-upload.filed.com/upload
You can also upload from a URL using the Partner Upload endpoint:
curl -X POST \
  -H "Authorization: Bearer <your-partner-jwt-token>" \
  -F "url=https://example.com/file.pdf" \
  -F "fileName=document.pdf" \
  -F "mimeType=application/pdf" \
  https://partner-upload.filed.com/upload
Partner-specific endpoint: The Partner Upload endpoint uses partner-specific JWT tokens with scoped permissions, providing better security than the upload-proxy endpoint.

FOR CUSTOMERS: Upload-proxy Endpoint
Customers: If you’re integrating as a customer, you can use the upload-proxy endpoint (https://upload-proxy.filed.com/upload) shown in the examples above. This endpoint uses your access token for authentication.
Partners: Partners should NOT use the upload-proxy endpoint. Partners must use the Partner Upload endpoint (https://partner-upload.filed.com/upload) shown in the section above.

Step 3b: Create work artifacts

After uploading the file, use the returned values to create work artifacts. Map the upload response fields to the artifact input:
  • Upload response mimeType → Artifact type
  • Upload response fileName → Artifact name
  • Upload response fileUrl → Artifact url
mutation CreateJobWorkArtifacts($jobWorkId: ID!, $inputs: [CreateJobWorkArtifactsInput!]!) {
  createJobWorkArtifacts(jobWorkId: $jobWorkId, inputs: $inputs) {
    id
    createdAt
    updatedAt
    workspaceId
    artifactId
    connectionJobId
  }
}

Implementation notes

  • Upload first: You must upload files to Filed’s upload endpoint before creating artifacts
  • Field mapping: Map upload response fields to artifact inputs:
    • mimeTypetype
    • fileNamename
    • fileUrlurl
  • Use descriptive types: Use the MIME type from the upload response (e.g., “application/pdf”, “image/jpeg”)
  • Multiple files: Upload each file separately, then create artifacts for each uploaded file
  • File URL: The fileUrl from the upload response is what Filed uses to access the file
Field Mapping: When creating artifacts, map the upload response fields as follows:
  • Upload mimeType → Artifact type
  • Upload fileName → Artifact name
  • Upload fileUrl → Artifact url

Step 4: Initiate tax preps import

After creating the connection job, attaching works, and adding artifacts, initiate the tax prep import to process all clients in the job. This triggers Filed to parse and import all tax preparations associated with the connection job.
For complete API reference, see Initiate tax preps import.

GraphQL mutation

mutation InitiateTaxPrepsImport($connectionJobId: ID!) {
  initiateTaxPrepsImport(connectionJobId: $connectionJobId) {
    id
    connectionId
    workspaceId
    name
    status
    createdAt
    updatedAt
    metadata
  }
}

Implementation notes

  • Prerequisites: Ensure you have completed Steps 1-3 before initiating the import:
    • Created a connection job
    • Attached works (clients) to the job
    • Attached work artifacts (files) to each work
  • Status monitoring: Monitor the status field to track import progress
  • Metadata: Check the metadata field for progress information or error details
  • Async processing: The import process runs asynchronously; the status will update as processing progresses

Integration Pattern 2: Filed Pulling Clients

This pattern allows Filed to discover and fetch clients from your platform on-demand. For this integration pattern, you need to provide API documentation for your platform’s APIs that Filed engineers will use to build the integration.
Important: This section is about documenting your platform’s APIs, not Filed’s APIs. Filed engineers will use your API documentation to build the integration that pulls clients from your platform.

Required API Documentation

You need to provide comprehensive API documentation for the following endpoints that Filed will use:

1. Authentication documentation

Document how Filed should authenticate to your platform’s API. This should include:
  • Authentication method (API key, OAuth, Bearer token, etc.)
  • How to obtain credentials
  • How to include credentials in requests (headers, query parameters, etc.)
  • Token refresh process (if applicable)
  • Rate limiting and quotas
  • Error responses for authentication failures
Example: If your platform uses API keys, document the header format (e.g., Authorization: Bearer <api_key> or X-API-Key: <api_key>). If using OAuth, document the token endpoint and refresh flow.

2. List of clients

Document your API endpoint that returns a list of clients. Include:
  • Endpoint URL: Full URL path (e.g., GET /api/v1/clients)
  • Authentication: How to authenticate the request
  • Query parameters: Pagination, filtering, sorting options
  • Request format: Headers, body (if POST)
  • Response format: JSON schema with all fields
  • Response fields:
    • Client ID (unique identifier)
    • Client name
    • Email
    • Phone
    • Type/category
    • Last modified date
    • Any other relevant fields
  • Pagination: How pagination works (offset/limit, cursor-based, etc.)
  • Error handling: Error codes and messages
Example Response Format: Document the exact JSON structure your API returns, including field names, types, and whether fields are required or optional.

3. List files for a client

Document your API endpoint that returns files for a specific client. Include:
  • Endpoint URL: Full URL path (e.g., GET /api/v1/clients/{clientId}/files)
  • Authentication: How to authenticate the request
  • Path parameters: Client ID format and requirements
  • Query parameters: Pagination, filtering, file type filters
  • Request format: Headers, body (if POST)
  • Response format: JSON schema with all fields
  • Response fields:
    • File ID (unique identifier)
    • File name
    • File size (in bytes)
    • MIME type
    • Download URL (how Filed can download the file)
    • Date created
    • Date modified
    • Any other relevant metadata
  • Pagination: How pagination works
  • Error handling: Error codes and messages
Download URL: The download URL in your response must be accessible to Filed using the connection credentials. Document how Filed should use these URLs to download files.

4. Download file

Document your API endpoint that allows Filed to download a file. Include:
  • Endpoint URL: Full URL path (e.g., GET /api/v1/files/{fileId}/download)
  • Authentication: How to authenticate the request
  • Path parameters: File ID format
  • Request format: Headers required
  • Response format:
    • HTTP status codes
    • File content (binary or base64)
    • Content-Type header
    • Content-Disposition header (if applicable)
  • Error handling: Error codes and messages
  • File access: How long download URLs remain valid (if using signed URLs)
File Access: Ensure your download endpoints accept the same authentication credentials used for other API calls. Document any special requirements for file downloads (e.g., signed URLs, temporary tokens).

5. Post notes on the client

Document your API endpoint that allows Filed to post notes or comments on a client. Include:
  • Endpoint URL: Full URL path (e.g., POST /api/v1/clients/{clientId}/notes)
  • Authentication: How to authenticate the request
  • Path parameters: Client ID format
  • Request format:
    • Headers (Content-Type, etc.)
    • Request body schema:
      • Note content/text
      • Note type/category (if applicable)
      • Author/user information (if applicable)
      • Timestamp (if not auto-generated)
  • Response format: JSON schema with created note details
  • Response fields:
    • Note ID
    • Note content
    • Created date
    • Author information
    • Any other relevant fields
  • Error handling: Error codes and messages
Note Format: Document the exact format for notes, including any formatting requirements (markdown, plain text, HTML), character limits, and required vs optional fields.

6. Upload file to the client

Document your API endpoint that allows Filed to upload files to a client. Include:
  • Endpoint URL: Full URL path (e.g., POST /api/v1/clients/{clientId}/files)
  • Authentication: How to authenticate the request
  • Path parameters: Client ID format
  • Request format:
    • Headers (Content-Type, Content-Length, etc.)
    • Request body: multipart/form-data or binary
    • File metadata (name, type, description, etc.)
  • Upload method:
    • Standard HTTP POST
    • TUS (resumable upload) protocol support
    • Chunked upload support
  • Response format: JSON schema with uploaded file details
  • Response fields:
    • File ID
    • File name
    • File URL
    • File size
    • Upload status
    • Any other relevant fields
  • File size limits: Maximum file size, chunk size (if chunked)
  • Error handling: Error codes and messages
TUS Protocol: If Filed uses TUS (resumable upload) protocol, document your TUS endpoint implementation, including the TUS protocol version, supported extensions, and any custom headers or parameters required.

Documentation Best Practices

When providing API documentation for Filed engineers:
  1. Be comprehensive: Include all details needed to make API calls successfully
  2. Provide examples: Include cURL, HTTP request/response examples for each endpoint
  3. Document errors: List all possible error codes and their meanings
  4. Include schemas: Provide JSON schemas or OpenAPI/Swagger specifications
  5. Test credentials: Provide test/sandbox credentials for Filed to test the integration
  6. Versioning: Document API versioning strategy and how to specify API versions
  7. Rate limits: Document rate limits, quotas, and throttling behavior
  8. Webhooks (if applicable): Document any webhooks your platform supports for real-time updates
Contact: Share your API documentation with your Filed account representative or integration team. They will coordinate with Filed engineers to build the integration using your documented APIs.

Complete Integration Example

Here’s a complete example showing the push pattern workflow:
const GRAPHQL_ENDPOINT = 'https://gateway.filed.com/graphql';
const connectionId = 'connection_789';

// Step 1: Create connection job
const createJobResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': 'my-sample-platform'
  },
  body: JSON.stringify({
    query: `
      mutation CreateConnectionJob($connectionId: ID!, $jobName: String!) {
        createConnectionJob(connectionId: $connectionId, jobName: $jobName) {
          id
        }
      }
    `,
    variables: {
      connectionId,
      jobName: '2024 Tax Season Import'
    }
  })
});

const { id: connectionJobId } = (await createJobResponse.json()).data.createConnectionJob;

// Step 2: Create job works (attach clients)
const createJobWorksResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': 'my-sample-platform'
  },
  body: JSON.stringify({
    query: `
      mutation CreateJobWorks($connectionJobId: ID!, $inputs: [CreateJobWorksInput!]!) {
        createJobWorks(connectionJobId: $connectionJobId, inputs: $inputs) {
          id
          workId
        }
      }
    `,
    variables: {
      connectionJobId,
      inputs: [
        {
          name: 'John Smith - 2024 Tax Return',
          externalId: 'client-12345'
        }
      ]
    }
  })
});

const [{ id: jobWorkId }] = (await createJobWorksResponse.json()).data.createJobWorks;

// Step 3: Create job work artifacts (attach files)
await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': 'my-sample-platform'
  },
  body: JSON.stringify({
    query: `
      mutation CreateJobWorkArtifacts($jobWorkId: ID!, $inputs: [CreateJobWorkArtifactsInput!]!) {
        createJobWorkArtifacts(jobWorkId: $jobWorkId, inputs: $inputs) {
          id
        }
      }
    `,
    variables: {
      jobWorkId,
      inputs: [
        {
          name: 'W-2 Form 2024',
          type: 'w2',
          url: 'https://api.example.com/files/w2-2024.pdf',
          externalId: 'file-12345'
        }
      ]
    }
  })
});

// Step 4: Initiate tax preps import
const initiateImportResponse = await fetch(GRAPHQL_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'source-platform': 'my-sample-platform'
  },
  body: JSON.stringify({
    query: `
      mutation InitiateTaxPrepsImport($connectionJobId: ID!) {
        initiateTaxPrepsImport(connectionJobId: $connectionJobId) {
          id
          status
        }
      }
    `,
    variables: {
      connectionJobId
    }
  })
});

const importResult = (await initiateImportResponse.json()).data.initiateTaxPrepsImport;
console.log(`Tax prep import initiated. Status: ${importResult.status}`);

Best Practices

Security

  1. Protect file URLs: Ensure file URLs are only accessible with proper authentication
  2. Validate credentials: Verify connection credentials have appropriate permissions
  3. Use HTTPS: Always use HTTPS for file URLs and API endpoints
  4. Secure storage: Store access tokens securely and never commit them to version control

Error handling

  1. Handle failures gracefully: Implement retry logic for transient failures
  2. Validate responses: Check for errors in GraphQL responses
  3. Log errors: Maintain error logs for debugging and monitoring
  4. Test file access: Verify file URLs are accessible before creating artifacts

Performance

  1. Batch operations: Create multiple works and artifacts in single requests when possible
  2. Pagination: Implement pagination for large client and file lists
  3. Async processing: Use async/await or background jobs for large imports
  4. Monitor progress: Track connection job status and work completion

Data management

  1. Use external IDs: Always provide externalId values to enable correlation with your system
  2. Descriptive names: Use clear, descriptive names for jobs, works, and artifacts
  3. Metadata: Include relevant metadata (file size, mime type, dates) in artifacts
  4. Idempotency: Design your integration to handle retries and duplicate prevention

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 create connection job, create job works, create job work artifacts, and initiate tax preps import
  2. Test the flow: Create test connection jobs and verify all steps work correctly
  3. Monitor usage: Track API usage and tax prep creation metrics
  4. Iterate: Gather feedback and refine your integration based on needs
  5. Scale: Automate the process to handle multiple tax preparations efficiently