📊 Excel filtering API

Filter Excel files and get matching rows as JSON.

Upload an Excel spreadsheet, define one or more filters, and receive the matching rows as structured JSON. Built for applications that need to process Excel data without manually opening or manipulating spreadsheets.

1

Upload your Excel file

Send an .xlsx file to the filtering endpoint using a multipart form request.

2

Define your filters

Specify the worksheet, column, filter name, and values you want to match.

3

Receive matching rows

The API returns each filter's matching rows together with the total number of matching rows.

How it works

The API processes the uploaded Excel workbook synchronously. Your request contains the Excel file and the filters you want to apply. The API validates the workbook, applies each filter independently, and immediately returns the matching rows.

Send Request
Validate Request
Apply Filters
JSON Result

Filter behavior

Behavior Description
Multiple filters Each filter is evaluated independently and gets its own result in the response.
Multiple values Values within a filter use OR matching.
Empty values values: [] matches every value in the specified column, including blank cells.
Column matching Column names are case-sensitive. Status and status are different columns.
Value matching Values are compared using their actual types rather than converting everything to strings.
Duplicate rows Duplicate Excel rows are preserved. The API does not deduplicate results.

Your first request

The following example filters an Excel spreadsheet using the Status column and returns separate results for successful and failed rows.

POST /v1/filter/
Python
import json
import requests

url = "https://filterapi.zendix.app/v1/filter/"

headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}

filters = [
    {
        "name": "successful",
        "column": "Status",
        "values": ["successful"]
    },
    {
        "name": "failed",
        "column": "Status",
        "values": ["failed"]
    }
]

with open("transactions.xlsx", "rb") as excel_file:

    response = requests.post(
        url,
        headers=headers,
        files={
            "file": (
                "transactions.xlsx",
                excel_file,
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            )
        },
        data={
            "filters": json.dumps(filters)
        },
        timeout=60
    )

print(response.json())
JavaScript
const formData = new FormData();

const filters = [
  {
    name: "successful",
    column: "Status",
    values: ["successful"]
  },
  {
    name: "failed",
    column: "Status",
    values: ["failed"]
  }
];

formData.append(
  "filters",
  JSON.stringify(filters)
);

formData.append(
  "file",
  fileInput.files[0]
);

const response = await fetch(
  "https://filterapi.zendix.app/v1/filter/",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY"
    },
    body: formData
  }
);

const data = await response.json();

console.log(data);
cURL
curl -X POST https://filterapi.zendix.app/v1/filter/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@transactions.xlsx" \
  -F 'filters=[{"name":"successful","column":"Status","values":["successful"]},{"name":"failed","column":"Status","values":["failed"]}]'
JSON Response
{
    "success": true,
    "data": {
        "successful": {
            "rows": [
                {
                    "ID": 1,
                    "Customer": "John",
                    "Status": "successful",
                    "Amount": 5000
                }
            ],
            "total_rows": 1
        },
        "failed": {
            "rows": [
                {
                    "ID": 2,
                    "Customer": "Mary",
                    "Status": "failed",
                    "Amount": 3000
                }
            ],
            "total_rows": 1
        }
    }
}

Authentication

All API requests must include your API key in the Authorization header using the Bearer format.

Keep your API keys secure

Your API keys should be kept secret and secure. Never expose them in frontend applications, public repositories, or client-side code.

1

Create an API key

Create or obtain an API key from your account dashboard.

2

Include it in requests

Send the key using the Authorization: Bearer YOUR_API_KEY header.

Python
headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}
JavaScript
const headers = {
  Authorization: "Bearer YOUR_API_KEY"
};
cURL
curl https://filterapi.zendix.app/v1/filter/ \
  -H "Authorization: Bearer YOUR_API_KEY"

Authentication errors

Requests with missing or invalid API keys are rejected with a standardized error response.

Invalid API Key
{
    "success": false,
    "error": {
        "code": "authentication_failed",
        "message": "Invalid API key."
    }
}

Filter Excel

Filter an Excel workbook by one or more column values. The endpoint accepts an .xlsx file using multipart form data and returns matching rows as JSON.

POST /v1/filter/

Request fields

Field Type Required Description
file File yes The Excel workbook to filter. Only .xlsx files are supported.
sheet string optional The worksheet to process. If omitted, the first worksheet in the workbook is used.
filters JSON array yes A list containing one or more filter objects.

Filter object

Each object inside filters defines one independent result group.

Field Type Required Description
name string yes Name of the result group. It becomes the key in the response. Names must be unique and must not exceed 100 characters.
column string yes The exact column name to filter. Column matching is case-sensitive.
values array yes Values to match in the specified column. Multiple values are treated as OR conditions.
Empty values

If values is an empty array, the filter matches every row where the specified column exists, including rows where that cell is blank.

Example request

JSON
{
    "sheet": "Transactions",
    "filters": [
        {
            "name": "successful",
            "column": "Status",
            "values": ["successful"]
        },
        {
            "name": "failed",
            "column": "Status",
            "values": ["failed"]
        }
    ]
}

Multiple values

Multiple values inside the same filter are treated as OR conditions.

Example
{
    "name": "pending_or_failed",
    "column": "Status",
    "values": ["pending", "failed"]
}

This matches rows where Status is either pending or failed.

Filter matching

Values are compared using their actual types. The API does not convert Excel values and filter values into strings before comparison.

Excel value Filter value Match
500 500 Yes
500.0 500 Yes
"500" 500 No
true 1 No
"successful" "successful" Yes

Excel structure requirements

The workbook must follow a predictable structure so that no spreadsheet data is silently discarded.

No silent data loss

If the workbook contains data that does not belong to a named column, the API rejects the workbook instead of silently ignoring that data.

Request examples

Python
import json
import requests

url = "https://filterapi.zendix.app/v1/filter/"

headers = {
    "Authorization": "Bearer YOUR_API_KEY"
}

filters = [
    {
        "name": "successful",
        "column": "Status",
        "values": ["successful"]
    },
    {
        "name": "failed",
        "column": "Status",
        "values": ["failed"]
    }
]

with open("transactions.xlsx", "rb") as excel_file:

    response = requests.post(
        url,
        headers=headers,
        files={
            "file": (
                "transactions.xlsx",
                excel_file,
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            )
        },
        data={
            "sheet": "Transactions",
            "filters": json.dumps(filters)
        },
        timeout=60
    )

print(response.status_code)
print(response.json())
JavaScript
const formData = new FormData();

const filters = [
  {
    name: "successful",
    column: "Status",
    values: ["successful"]
  },
  {
    name: "failed",
    column: "Status",
    values: ["failed"]
  }
];

formData.append(
  "sheet",
  "Transactions"
);

formData.append(
  "filters",
  JSON.stringify(filters)
);

formData.append(
  "file",
  fileInput.files[0]
);

const response = await fetch(
  "https://filterapi.zendix.app/v1/filter/",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY"
    },
    body: formData
  }
);

const data = await response.json();

console.log(data);
cURL
curl -X POST https://filterapi.zendix.app/v1/filter/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@transactions.xlsx" \
  -F "sheet=Transactions" \
  -F 'filters=[{"name":"successful","column":"Status","values":["successful"]},{"name":"failed","column":"Status","values":["failed"]}]'

Response

Each filter name becomes a key inside data. Every result contains the matching rows and the number of matching rows.

JSON Response
{
    "success": true,
    "data": {
        "successful": {
            "rows": [
                {
                    "ID": 1,
                    "Customer": "John",
                    "Status": "successful",
                    "Amount": 5000
                },
                {
                    "ID": 3,
                    "Customer": "David",
                    "Status": "successful",
                    "Amount": 7200
                }
            ],
            "total_rows": 2
        },
        "failed": {
            "rows": [
                {
                    "ID": 2,
                    "Customer": "Mary",
                    "Status": "failed",
                    "Amount": 3000
                }
            ],
            "total_rows": 1
        }
    }
}

Rate limiting

The API enforces rate limits to help maintain fair usage, reliability, and system stability.

Rate limits are applied per user

Each user has its own request limit. Requests from different users are tracked separately.

Type Rate Limit Window
User 60 requests per minute

Each user can make a maximum of 60 requests per minute.

File & data limits

The API enforces limits on uploaded workbooks and the amount of spreadsheet data processed in a request.

Limit Value
Maximum file size 5 MB
Maximum data rows 10,000 non-empty rows
Supported format .xlsx
Header row Row 1
Empty rows do not count toward the row limit

Completely empty rows are ignored and do not count toward the 10,000-row maximum.

What happens when a limit is exceeded?

The API rejects the request and returns a standardized error response. No partial result is returned.

Error codes

Errors follow a standardized structure to make failures predictable and easy to handle programmatically.

Error response format
{
    "success": false,
    "error": {
        "code": "error_code",
        "message": "Human readable message"
    }
}

Common error codes

Code Meaning
validation_error The request data is invalid or a required field is missing.
method_not_allowed The HTTP method is not supported by the endpoint.
rate_limit_exceeded The API key has exceeded its allowed request rate.
authentication_failed The API key is missing or invalid.
parse_error The request body or multipart form data could not be parsed.
invalid_workbook The uploaded file is not a valid readable .xlsx workbook.
sheet_not_found The requested worksheet does not exist in the workbook.
column_not_found A requested filter column does not exist in the selected worksheet.
duplicate_column The worksheet contains duplicate column names.
unnamed_column The worksheet contains data under an unnamed column or beyond the header range.
row_limit_exceeded The worksheet contains more than 10,000 non-empty data rows.

Example errors

Column not found
{
    "success": false,
    "error": {
        "code": "column_not_found",
        "message": "Column 'Status' was not found in worksheet 'Transactions'."
    }
}
Invalid workbook
{
    "success": false,
    "error": {
        "code": "invalid_workbook",
        "message": "The uploaded file is not a valid .xlsx workbook."
    }
}
Row limit exceeded
{
    "success": false,
    "error": {
        "code": "row_limit_exceeded",
        "message": "Worksheet 'Transactions' contains more than 10,000 data rows."
    }
}