Skip to main content
Version: v3.0

API reference

This page documents Flatfile's REST API, focused mainly around retrieving data from Flatfile.


info

We are continuing to develop new endpoints based on developer feedback. Please reach out to Support to share your thoughts on how we can improve our APIs to support your needs.

Hosts

The primary host is api.us.flatfile.io for both read and write operations. All API access must use HTTPS.

Format

The entire API uses JSON encoded as UTF-8.

The body of POST and PUT requests must be either a JSON object or a JSON array (depending on the particular endpoint) and their Content-Type header should be set to application/json; charset=UTF-8.

The body of responses is always a JSON object, and their content type is always application/json; charset=UTF-8.

Managing access keys

You will need an access key to make API requests, and access keys are managed within your Flatfile account dashboard. To create an access key and start making reqests:

  1. Visit your Flatfile account dashboard.
  2. In the bottom-left corner you should see a User Profile area. Click on this area to open a menu, and select Settings.
  3. On the Account Settings page, under the "Account Settings" section at the bottom of the page, click the Manage access keys button. You can create new access keys and also deactivate any previously generated access keys on this page.
  4. Click the Create access key button. In the modal, enter a reference name in the "Memo" field and click the Create button.
  5. Next you will see a new modal with an "Access Key Id" and the associated "Secret Access Key"; the latter is only displayed once, so do not forget to copy it before continuting to avoid repeating this process again. This key pair grants you access to whichever API you choose. Note that access keys are assigned to your User Profile, and are not visible to other users in your team.
Using Access Keys

You can provide API Authorization via either the header: "X-Api-Key": "Access_Key_Id+Secret_Access_Key (must include the + sign) or "Authorization": "Bearer <token>".

how to generate access keys within the flatfile dashboard

Endpoints

POST Exchange access key for JWT

Endpoint: /auth/access-key/exchange

Request Body:

NameRequiredTypeValueDescription
accessKeyIdtruestringAccess Key generated in app
expiresInnumber43200 (default)Sets an expiration (in seconds)
secretAccessKeytruestringSecret Access Key generated in app

Example Response:

type JWT = string;

interface Reponse {
accessToken: JWT;
user: {
id: number;
name: string;
email: string;
type: "other" | "unknown";
jobTitle: Nullable<string>;
githubUsername: Nullable<string>;
trialEndsAt: Nullable<ISO_8601>;
lastLoginAt: ISO_8601;
createdAt: ISO_8601;
updatedAt: ISO_8601;
};
}

GET Download an upload

Endpoint: /batch/:batchId/export.csv

Path Variables:

NameRequiredTypeValueDescription
batchIdtruestringA valid UUID

Query Params:

NameRequiredTypeValueDescription
typetruestringEnum: original, processedFile to download

Response: Binary Data

DELETE Delete an upload

Endpoint: /batch/:batchId

Path Variables:

NameRequiredTypeValueDescription
batchIdtruestringA valid UUID

Example Reponse:

interface Response extends Batch {
__schema__: Schema;
__embed__: Embed;
}

GET Bulk delete uploads

Endpoint: /delete/batches

Query Params:

NameRequiredTypeValueDescription
olderThanQuantitytruestring
olderThanUnittruestringEnum: minute, hour, day, week, month
sendEmailtruestringEnum: true, false
teamIdtruestring

Example Reponse:

interface Response {
success: true;
}

GET List Workspace uploads

Endpoint: /rest/batches

Query Params:

NameRequiredTypeValueDescription
endUserIdstringValid endUserId for the Workspace
environmentIdstringValid environmentId for the Workspace
licenseKeytruestringA valid licenseKey for the Workspace
searchstringSearches fileName, originalFile, memo
skipnumber0 (default)The rows to skip before listing
takenumber50 (default)The maximum number of rows to return
workspaceIdstringValid workspaceId for the Workspace

Example Reponse:

interface Response {
pagination: {
currentPage: number;
limit: number;
offset: number;
onPage: number;
nextOffset: number;
totalCount: number;
pageCount: number;
};
data: Array<Batch>;
}

GET File upload meta data

Endpoint: /rest/batch/:batchId

Path Variables:

NameRequiredTypeValueDescription
batchIdtruestringA valid UUID

Example Reponse:

interface Response extends Batch {
__schema__: Schema;
__embed__: Embed;
__endUser__: EndUser;
__has_endUser__: boolean;
}

GET Sheet name for file upload

Endpoint: /upload/:uploadId/dataSources

Path Variables:

NameRequiredTypeValueDescription
uploadIdtruestringA valid UUID
  • uploadId can be found in the filename string: "license-53674a8c-db40-4cb4-b949-63547207b58b/batch-89fm0375-2760-4bb0-8359-6f62ba35c597/upload-dbf6f99c-851c-4aea-994c-97e0d203f178.xlsx". It's the UUID immediately following "upload-".

Query Params:

NameRequiredTypeValueDescription
licenseKeystringA valid licenseKey for the Workspace

Example Response:

interface Response {
uploadId: UUID;
index: number;
label: string;
rowCount: number;
columnCount: number;
hasError: boolean;
errorMsg: string;
errorType: number;
path: Nullable<string>;
}

GET Records for file upload

Endpoint: /rest/batch/:batchId/rows

Path Variables:

NameRequiredTypeValueDescription
batchIdtruestringA valid UUID

Query Params:

NameRequiredTypeValueDescription
createdAtEndDatestringISO 8601The maximum createdAt date to return
createdAtStartDatestringISO 8601The minimum createdAt date to return
deletedstringEnum: true, t, y, false, f, nReturn only deleted rows
skipnumber0 (default)The rows to skip before listing
takenumber50 (default)The maximum number of rows to return
updatedAtEndDatestringISO 8601The maximum updatedAt date to return
updatedAtStartDatestringISO 8601The minimum updatedAt date to return
validstringEnum: true, t, y, false, f, nReturn only valid rows

Example Reponse:

interface Response {
pagination: {
currenPage: number;
limit: number;
offset: number;
onPage: number;
totalCount: number;
pageCount: number;
};
data: Array<{
id: UUID;
mapped: Record<string, any>;
}>;
}

POST Upload to Workspace sheet

Endpoint: /workspace/:workspaceId/sheet/:sheetId/data

Path Variables:

NameRequiredTypeValueDescription
sheetIdtruestringA valid UUID
workspaceIdtruestringA valid UUID

Request Body:

interface Response {
data: Array<Record<string, any>>;
}

Example Response:

interface Response {
rows: Array<{
_id: number;
cells: Record<
string,
{
value: Nullable<any>;
}
>;
externalId: Nullable<string>;
validations: Array<{
key: string;
type: "type" | "value";
error: string;
message: string;
}>;
status: RecordStatus;
}>;
totalRows: number;
accepted: number;
dismissed: number;
filtered: number;
counts: {
valid: number;
invalid: number;
merged: number;
};
requestId: string;
}

GET Fetch Workspace sheet records

Endpoint: /workspace/:workspaceId/sheet/:sheetId/records

Path Variables:

NameRequiredTypeValueDescription
sheetIdtruestringA valid UUID
workspaceIdtruestringA valid UUID

Query Params:

NameRequiredTypeValueDescription
filterstringEnum: review, dismissed, acceptedReturn only the filtered rows
mergeIdstring
nestedboolean
recordIdsstring[]
skipnumber0 (default)The rows to skip before listing
takenumber50 (default)The maximum number of rows to return
validstringEnum: true, t, y, false, f, nReturn only valid rows

Example Response:

interface Response {
rows: Array<{
_id: number;
cells: Record<
string,
{
value: any;
}
>;
validations: Array<{
error: string;
key: string;
message: string;
}>;
status: RecordStatus;
externalId: Nullable<string>;
}>;
totalRows: number;
accepted: number;
dismissed: number;
filtered: number;
counts: {
valid: number;
invalid: number;
merged: number;
};
}

GET List team Workspaces

Endpoint: /rest/teams/:teamId/workspaces

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring

Query Params:

NameRequiredTypeValueDescription
environmentIdstringValid environmentId for the Workspace
skipnumber0 (default)The rows to skip before listing
takenumber50 (default)The maximum number of rows to return

Example Reponse:

interface Response {
pagination: {
currenPage: number;
limit: number;
offset: number;
onPage: number;
totalCount: number;
pageCount: number;
};
data: Array<Workspace>;
}

GET Detail Workspace

Endpoint: /rest/workspace/:workspaceId

Path Variables:

NameRequiredTypeValueDescription
workspaceIdtruestringA valid UUID

Example Reponse:

interface Response extends Workspace {}

POST Invite Workspace collaborator

Endpoint: /rest/teams/:teamId/workspaces/:workspaceId/invitations

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring
workspaceIdtruestringA valid UUID

Request Body:

NameRequiredTypeValueDescription
emailtruestringEmail address of invited collaborator

Example Reponse:

interface Response {
success: boolean;
message?: string;
}

GET List Workspace invitations

Endpoint: /rest/teams/:teamId/workspaces/:workspaceId/invitations

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring
workspaceIdtruestringA valid UUID

Example Reponse:

interface Invitation {
deleted: boolean;
expired: boolean;
id: UUID;
workspaceId: UUID;
adminTeamId: number;
organizationId: UUID;
name: string;
email: string;
token: UUID;
invitedById: Nullable<number>;
createdAt: ISO_8601;
updatedAt: ISO_8601;
activatedAt: ISO_8601;
deletedAt: Nullable<ISO_8601>;
}

type Response = Array<Invitation>;

GET List Workspace collaborators

Endpoint: /rest/teams/:teamId/workspaces/:workspaceId/collaborators

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring
workspaceIdtruestringA valid UUID

Example Reponse:

interface Collaborator {
id: number;
name: string;
oauthGitHubId: Nullable<string>;
email: string;
githubUsername: Nullable<string>;
trialEndsAt: Nullable<ISO_8601>;
lastLoginAt: Nullable<ISO_8601>;
createdAt: ISO_8601;
updatedAt: ISO_8601;
}

type Response = Array<Collaborator>;

DELETE Revoke Workspace invitation

Endpoint: /rest/teams/:teamId/workspaces/:workspaceId/invitations

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring
workspaceIdtruestringA valid UUID

Request Body:

NameRequiredTypeValueDescription
emailtruestringEmail address of invited collaborator

Example Reponse:

interface Response {
success: boolean;
message?: string;
}

DELETE Remove Workspace collaborator

Endpoint: /rest/teams/:teamId/workspaces/:workspaceId/collaborators/:userId

Path Variables:

NameRequiredTypeValueDescription
teamIdtruestring
userIdtruestring
workspaceIdtruestringA valid UUID

Request Body:

NameRequiredTypeValueDescription
emailtruestringEmail address of collaborator

Example Reponse:

interface Response {
success: boolean;
message?: string;
}

Common types

type UUID = string; /* 021f68c8-68f6-4910-8d07-9c505683b1d4 */

type ISO_8601 = string; /* 2022-05-20T17:28:58.000Z */

type BatchStatus =
/* anywhere from embed is opened to file started upload but did not finish / was not parsed */
| "created"
/* anywhere from file was uploaded and parsed through importer saw header selection but did not proceed */
| "header_confirmed"
/* anywhere from importer continued past header selection to some mapping done (even by us) */
| "imported"
/* anywhere from we automapped some fields to the user mapped fields but did not continue to review */
| "matched"
/* anywhere from importer continued after mapping (including loading time) until the data was submitted in review */
| "partial_matched"
/* data was submitted */
| "submitted";

type RecordStatus =
/* a record still in review */
| "review"
/* a record explicity set to be dismissed */
| "dismissed"
/* a record explicity set to be accepted */
| "accepted";

type BatchType =
/* Legacy */
| 0
/* Throw away -- do not use */
| 1
/* File Upload */
| 2
/* Robot */
| 3;

type Nullable<A> = A | null; /* any value of type A or null */

type UploadSource = 1; /* SFTP */

interface Embed {
id: UUID;
archived: boolean;
name: string;
teamId: number;
environmentId: UUID;
helpContent: Nullable<string>;
privateKeyId: number;
legacyWebhookURL: Nullable<string>;
createdById: number;
createdAt: ISO_8601;
updatedAt: ISO_8601;
deleted: boolean;
deletedById: Nullable<number>;
deletedAt: Nullable<ISO_8601>;
}

interface Workspace {
id: UUID;
environmentId: UUID;
primaryWorkbookId: UUID;
secureEnvId: Nullable<UUID>;
name: string;
slug: Nullable<string>;
sessionKey: Nullable<string>;
status: number;
type: number;
dataEngine: number;
createdAt: ISO_8601;
updatedAt: ISO_8601;
deleted: Nullable<boolean>;
}

interface Schema {
id: number;
name: string;
ancestorId: number;
variantOfId: Nullable<number>;
rootId: number;
version: number;
archived: boolean;
teamId: number;
environmentId: UUID;
createdById: number;
jsonSchema: {
schema: {
properties: Record<
string,
{
default?: any;
enum?: Array<string>;
enumLabel?: Array<string>;
format?: string;
label: string;
maximum?: number;
minimum?: number;
regexp?: {
pattern: string;
flags: string;
ignoreBlanks: boolean;
};
schemaId?: string;
type: string;
visibility?: Partial<Record<"export" | "mapping" | "review", boolean>>;
}
>;
type: "object";
required: Array<string>;
unique: Array<string>;
};
};
importCount: number;
fieldCount: number;
createdAt: ISO_8601;
updatedAt: ISO_8601;
linkedSchemaIds: Array<number>;
previewFieldKey: Nullable<string>;
}

interface EndUser {
id: UUID;
userId: string;
name: string;
email: string;
companyId: string;
companyName: string;
teamId: number;
createdAt: Nullable<ISO_8601>;
updatedAt: Nullable<ISO_8601>;
}

interface Batch {
id: UUID;
licenseId: number;
teamId: number;
environmentId: UUID;
workspaceId: UUID;
schemaId: number;
embedId: UUID;
endUserId: UUID;
filename: Nullable<string>;
source: Nullable<UploadSource>;
memo: Nullable<string>;
validatedIn: Nullable<string>;
originalFile: Nullable<string>;
manual: Nullable<boolean>;
managed: Nullable<boolean>;
countRows: Nullable<number>;
countRowsInvalid: Nullable<number>;
countRowsAccepted: Nullable<number>;
countColumns: Nullable<number>;
countColumnsMatched: Nullable<number>;
headersRaw: Nullable<
Array<{
index: number;
letter: string;
value: string;
}>
>;
headersMatched: Nullable<
Array<{
index: number;
letter: string;
value: string;
matched_key: string;
}>
>;
status: Nullable<BatchStatus>;
type: BatchType;
targetSchema: null;
parsingConfig: null;
importedFromUrl: string;
headerHash: Nullable<string>;
failureReason: Nullable<string>;
matchedAt: Nullable<ISO_8601>;
submittedAt: Nullable<ISO_8601>;
failedAt: Nullable<ISO_8601>;
handledAt: Nullable<ISO_8601>;
writeAccessKey: Nullable<UUID>;
legacySettingsId: Nullable<UUID>;
legacyWebhookUrl: Nullable<string>;
legacyHasFieldHooks: Nullable<boolean>;
legacyHasRecordHooks: Nullable<boolean>;
createdAt: ISO_8601;
updatedAt: Nullable<ISO_8601>;
devMode: boolean;
deleted: boolean;
}