API Documentation

A complete reference for the PowerProjects.AI REST API. Upload files, manage data items, fields, and rows — all authenticated with your account API key.

Authentication

All API endpoints require an API key tied to your account. You can find your key in your account settings. Pass it via the X-Api-Key header or as an api_key query parameter.

The header approach is recommended for production use. Query parameters are convenient for quick testing.
# Via header (recommended)
curl -H "X-Api-Key: your_api_key_here" \
  https://powerprojects.ai/api/v1/data-items/

# Via query parameter
curl https://powerprojects.ai/api/v1/data-items/?api_key=your_api_key_here
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://powerprojects.ai/api/v1"
HEADERS = {"X-Api-Key": API_KEY}

response = requests.get(f"{BASE_URL}/data-items/", headers=HEADERS)
print(response.json())
const API_KEY = "your_api_key_here";
const BASE_URL = "https://powerprojects.ai/api/v1";

const res = await fetch(`${BASE_URL}/data-items/`, {
  headers: { "X-Api-Key": API_KEY }
});
const data = await res.json();
console.log(data);

Base URL

All endpoints are prefixed with:

https://powerprojects.ai/api/v1/

All request and response bodies use JSON, except file upload endpoints which use multipart/form-data.

Error Handling

The API returns standard HTTP status codes. Error responses include a JSON body with an error key describing what went wrong.

StatusMeaning
200Success
201Created successfully
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
404Not found — resource doesn't exist or doesn't belong to your account
405Method not allowed
401 Example error response
{
  "error": "Invalid or missing API key."
}

Create Data Item from File

Upload a CSV or Excel file to create a new data item. Fields are auto-detected from column headers and data types are inferred from the file content.

POST /api/v1/data-items/create-from-file/
ParameterTypeDescription
data_name string required Name for the data item
data_description string optional Description of the data
data_file file required CSV or Excel file (.csv, .xlsx, .xls)
This endpoint uses multipart/form-data, not JSON. Field types (char, decimal, date, boolean, text) are automatically detected from the data.
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -F "data_name=Q1 Sales Report" \
  -F "data_description=Quarterly sales by region" \
  -F "data_file=@/path/to/sales.csv" \
  https://powerprojects.ai/api/v1/data-items/create-from-file/
import requests

response = requests.post(
    f"{BASE_URL}/data-items/create-from-file/",
    headers=HEADERS,
    data={
        "data_name": "Q1 Sales Report",
        "data_description": "Quarterly sales by region",
    },
    files={
        "data_file": open("sales.csv", "rb")
    }
)
print(response.json())
201 Response
{
  "id": 42,
  "data_name": "Q1 Sales Report",
  "data_description": "Quarterly sales by region",
  "fields": [
    { "id": 101, "field_label": "Region", "field_type": "char", "field_order": 0 },
    { "id": 102, "field_label": "Revenue", "field_type": "decimal", "field_order": 1 },
    { "id": 103, "field_label": "Close Date", "field_type": "date", "field_order": 2 }
  ],
  "rows_created": 1250,
  "cells_created": 3750,
  "reference_file": { "id": 7, "filename": "sales.csv" }
}

Append Rows from File

Upload a file to add rows to an existing data item. Columns are matched to existing fields by header name (case-insensitive). Unmatched columns are skipped unless add_new_fields is set.

POST /api/v1/data-items/{id}/append-from-file/
ParameterTypeDescription
data_file file required CSV or Excel file
add_new_fields string optional Set to "true" to auto-create fields for unmatched columns
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -F "data_file=@/path/to/more_sales.csv" \
  -F "add_new_fields=true" \
  https://powerprojects.ai/api/v1/data-items/42/append-from-file/
response = requests.post(
    f"{BASE_URL}/data-items/42/append-from-file/",
    headers=HEADERS,
    data={"add_new_fields": "true"},
    files={"data_file": open("more_sales.csv", "rb")}
)
201 Response
{
  "id": 42,
  "data_name": "Q1 Sales Report",
  "rows_appended": 500,
  "cells_created": 2000,
  "matched_columns": ["Region", "Revenue", "Close Date"],
  "skipped_columns": [],
  "reference_file": { "id": 8, "filename": "more_sales.csv" }
}

Data Items

GET /api/v1/data-items/

Returns all data items belonging to your account.

curl -H "X-Api-Key: your_api_key_here" \
  https://powerprojects.ai/api/v1/data-items/
response = requests.get(f"{BASE_URL}/data-items/", headers=HEADERS)
items = response.json()["data_items"]
200 Response
{
  "data_items": [
    {
      "id": 42,
      "data_name": "Q1 Sales Report",
      "data_description": "Quarterly sales by region",
      "field_count": 3,
      "created_at": "2026-02-15T10:30:00+00:00",
      "updated_at": "2026-02-28T14:22:00+00:00"
    }
  ]
}
POST /api/v1/data-items/

Create a new data item with optional field definitions (no file upload). Use this when you want to define the schema manually, then add rows via the API.

ParameterTypeDescription
data_name string required Name for the data item
data_description string optional Description
fields array optional Array of field definitions (see example)
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "data_name": "Inventory Tracker",
    "data_description": "Weekly inventory levels",
    "fields": [
      {"field_label": "SKU", "field_type": "char"},
      {"field_label": "Quantity", "field_type": "decimal"},
      {"field_label": "Last Counted", "field_type": "date"}
    ]
  }' \
  https://powerprojects.ai/api/v1/data-items/
response = requests.post(
    f"{BASE_URL}/data-items/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "data_name": "Inventory Tracker",
        "data_description": "Weekly inventory levels",
        "fields": [
            {"field_label": "SKU", "field_type": "char"},
            {"field_label": "Quantity", "field_type": "decimal"},
            {"field_label": "Last Counted", "field_type": "date"},
        ]
    }
)
Valid field_type values: char, text, decimal, date, boolean
GET /api/v1/data-items/{id}/

Get full details for a data item including its fields, reference files, and row count.

200 Response
{
  "id": 42,
  "data_name": "Q1 Sales Report",
  "data_description": "Quarterly sales by region",
  "created_at": "2026-02-15T10:30:00+00:00",
  "updated_at": "2026-02-28T14:22:00+00:00",
  "fields": [
    { "id": 101, "field_label": "Region", "field_type": "char", "field_order": 0,
      "field_required": false, "field_instructions": "" }
  ],
  "reference_files": [
    { "id": 7, "filename": "sales.csv", "created_at": "2026-02-15T10:30:00+00:00" }
  ],
  "row_count": 1250
}
PATCH /api/v1/data-items/{id}/

Update a data item's name or description. Only include the fields you want to change.

curl -X PATCH \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"data_name": "Q1 Sales Report (Updated)"}' \
  https://powerprojects.ai/api/v1/data-items/42/
response = requests.patch(
    f"{BASE_URL}/data-items/42/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"data_name": "Q1 Sales Report (Updated)"}
)
DELETE /api/v1/data-items/{id}/

Permanently delete a data item and all of its fields, rows, and reference files.

This action is irreversible. All data, fields, rows, and uploaded reference files will be permanently removed.
curl -X DELETE \
  -H "X-Api-Key: your_api_key_here" \
  https://powerprojects.ai/api/v1/data-items/42/
200 Response
{ "deleted": true }

Fields

Fields define the columns/schema of a data item. Each field has a label, a type, and an order.

GET /api/v1/data-items/{id}/fields/

List all fields for a data item, ordered by field_order.

200 Response
{
  "fields": [
    {
      "id": 101,
      "field_label": "Region",
      "field_type": "char",
      "field_order": 0,
      "field_required": false,
      "field_instructions": ""
    }
  ]
}
POST /api/v1/data-items/{id}/fields/

Add a new field to a data item.

ParameterTypeDescription
field_labelstringrequiredColumn header name
field_typestringoptionalOne of: char, text, decimal, date, boolean. Default: char
field_orderintegeroptionalPosition in the column list
field_requiredbooleanoptionalWhether the field is required
field_instructionsstringoptionalInstructions or notes for this field
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"field_label": "Discount %", "field_type": "decimal"}' \
  https://powerprojects.ai/api/v1/data-items/42/fields/
response = requests.post(
    f"{BASE_URL}/data-items/42/fields/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"field_label": "Discount %", "field_type": "decimal"}
)
PATCH /api/v1/data-items/{id}/fields/{field_id}/

Update a field's label, type, order, or instructions. Only include the fields you want to change.

DELETE /api/v1/data-items/{id}/fields/{field_id}/

Delete a field. All values stored in this field will also be removed.

Rows

Rows represent the actual data in your data item. Each row is identified by a _row_ref and contains values keyed by field ID.

GET /api/v1/data-items/{id}/rows/

Get paginated rows. Values are keyed by field ID as strings.

Query ParamTypeDescription
offsetintegeroptionalStart index (default: 0)
limitintegeroptionalMax rows to return (default: 100, max: 500)
searchstringoptionalFull-text search across all cell values
curl -H "X-Api-Key: your_api_key_here" \
  "https://powerprojects.ai/api/v1/data-items/42/rows/?offset=0&limit=50"
response = requests.get(
    f"{BASE_URL}/data-items/42/rows/",
    headers=HEADERS,
    params={"offset": 0, "limit": 50, "search": "North"}
)
200 Response
{
  "total": 1250,
  "offset": 0,
  "limit": 50,
  "rows": [
    {
      "_row_ref": "0",
      "101": "North",
      "102": 45200.50,
      "103": "2026-01-15"
    }
  ]
}
Row values are keyed by field ID (e.g. "101" maps to field with id: 101). Use the Get Detail or List Fields endpoint to map IDs to labels.
POST /api/v1/data-items/{id}/rows/

Add a single row. Pass values keyed by field ID.

curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"values": {"101": "West", "102": 31500.00, "103": "2026-03-01"}}' \
  https://powerprojects.ai/api/v1/data-items/42/rows/
response = requests.post(
    f"{BASE_URL}/data-items/42/rows/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"values": {"101": "West", "102": 31500.00, "103": "2026-03-01"}}
)
201 Response
{ "row_ref": "1250", "cells_created": 3 }
POST /api/v1/data-items/{id}/rows/bulk/

Insert multiple rows in one request. Ideal for batch data ingestion.

curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      {"101": "East", "102": 28900.00, "103": "2026-03-01"},
      {"101": "South", "102": 42100.75, "103": "2026-03-01"}
    ]
  }' \
  https://powerprojects.ai/api/v1/data-items/42/rows/bulk/
rows = [
    {"101": "East",  "102": 28900.00, "103": "2026-03-01"},
    {"101": "South", "102": 42100.75, "103": "2026-03-01"},
]
response = requests.post(
    f"{BASE_URL}/data-items/42/rows/bulk/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"rows": rows}
)
201 Response
{ "rows_created": 2, "cells_created": 6 }
GET /api/v1/data-items/{id}/rows/{row_ref}/

Get a single row by its _row_ref.

200 Response
{
  "row": {
    "_row_ref": "0",
    "101": "North",
    "102": 45200.50,
    "103": "2026-01-15"
  }
}
PATCH /api/v1/data-items/{id}/rows/{row_ref}/

Update specific cells in a row. Only include the field IDs you want to change.

curl -X PATCH \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"values": {"102": 48000.00}}' \
  https://powerprojects.ai/api/v1/data-items/42/rows/0/
response = requests.patch(
    f"{BASE_URL}/data-items/42/rows/0/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"values": {"102": 48000.00}}
)
200 Response
{ "row_ref": "0", "cells_updated": 1, "cells_created": 0 }
DELETE /api/v1/data-items/{id}/rows/{row_ref}/

Delete an entire row and all of its cell values.

200 Response
{ "deleted": true, "cells_removed": 3 }

Summary & Statistics

GET /api/v1/data-items/{id}/summary/

Get aggregate statistics for every field in a data item. Returns type-aware summaries: min/max/sum/avg for decimals, top values for text, date ranges, and boolean counts.

curl -H "X-Api-Key: your_api_key_here" \
  https://powerprojects.ai/api/v1/data-items/42/summary/
response = requests.get(
    f"{BASE_URL}/data-items/42/summary/",
    headers=HEADERS
)
summary = response.json()
200 Response
{
  "id": 42,
  "data_name": "Q1 Sales Report",
  "row_count": 1250,
  "field_count": 3,
  "field_summaries": [
    {
      "field_id": 101,
      "field_label": "Region",
      "field_type": "char",
      "total_values": 1250,
      "empty_count": 0,
      "unique_count": 4,
      "top_values": [
        { "value": "North", "count": 412 },
        { "value": "South", "count": 380 },
        { "value": "East", "count": 298 },
        { "value": "West", "count": 160 }
      ]
    },
    {
      "field_id": 102,
      "field_label": "Revenue",
      "field_type": "decimal",
      "total_values": 1250,
      "empty_count": 0,
      "min": 1200.00,
      "max": 98500.00,
      "sum": 15680432.50,
      "avg": 12544.35
    },
    {
      "field_id": 103,
      "field_label": "Close Date",
      "field_type": "date",
      "total_values": 1248,
      "empty_count": 2,
      "min_date": "2026-01-02",
      "max_date": "2026-03-31"
    }
  ]
}

Dashboard Widgets

Widgets define chart visualizations on a data item's dashboard. Each widget references a label field, has one or more series for aggregation, and configurable chart options.

Chart types: bar, line, pie, doughnut, area, scatter, number
Widget sizes: sm (1/3 width), md (1/2 width), lg (full width)
Date groupings: day, week, month, quarter, year
GET /api/v1/data-items/{id}/widgets/

List all dashboard widgets for a data item, including their series.

200 Response
{
  "widgets": [
    {
      "id": 1,
      "data_item": 42,
      "title": "Revenue by Region",
      "description": "",
      "chart_type": "bar",
      "widget_order": 0,
      "widget_size": "md",
      "label_field": 101,
      "date_grouping": "",
      "sort_direction": "",
      "row_limit": null,
      "filter_config": null,
      "chart_options": null,
      "created_at": "2026-03-01T12:00:00+00:00",
      "updated_at": "2026-03-01T12:00:00+00:00",
      "series": [
        {
          "id": 1,
          "value_field": 102,
          "aggregation": "sum",
          "label": "Total Revenue",
          "series_order": 0,
          "color": "#0052FF"
        }
      ]
    }
  ]
}
POST /api/v1/data-items/{id}/widgets/

Create a new dashboard widget. You can optionally include a series array to create series in the same request.

ParameterTypeDescription
titlestringoptionalDisplay title for the widget
descriptionstringoptionalDescription or notes
chart_typestringoptionalOne of: bar, line, pie, doughnut, area, scatter, number
widget_sizestringoptionalOne of: sm, md, lg. Default: md
widget_orderintegeroptionalPosition in the dashboard layout
label_fieldintegeroptionalField ID to use as the label/x-axis
date_groupingstringoptionalOne of: day, week, month, quarter, year
sort_directionstringoptionalOne of: asc, desc
row_limitintegeroptionalMax rows to include in the chart
filter_configobjectoptionalJSON filter configuration
chart_optionsobjectoptionalAdditional JSON chart options
seriesarrayoptionalArray of series objects to create (see Series parameters)
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Revenue by Region",
    "chart_type": "bar",
    "widget_size": "md",
    "label_field": 101,
    "series": [
      {"value_field": 102, "aggregation": "sum", "label": "Total Revenue", "color": "#0052FF"}
    ]
  }' \
  https://powerprojects.ai/api/v1/data-items/42/widgets/
response = requests.post(
    f"{BASE_URL}/data-items/42/widgets/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "title": "Revenue by Region",
        "chart_type": "bar",
        "widget_size": "md",
        "label_field": 101,
        "series": [
            {"value_field": 102, "aggregation": "sum", "label": "Total Revenue", "color": "#0052FF"}
        ]
    }
)
201 Response
{
  "id": 1,
  "data_item": 42,
  "title": "Revenue by Region",
  "chart_type": "bar",
  "widget_size": "md",
  "series": [
    {
      "id": 1,
      "value_field": 102,
      "aggregation": "sum",
      "label": "Total Revenue",
      "series_order": 0,
      "color": "#0052FF"
    }
  ],
  // ... other widget fields
}
GET /api/v1/data-items/{id}/widgets/{widget_id}/

Retrieve a single widget with its series.

PATCH /api/v1/data-items/{id}/widgets/{widget_id}/

Update a widget's properties. Only include the fields you want to change. Series are managed separately via the series endpoints.

curl -X PATCH \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"title": "Updated Title", "chart_type": "line"}' \
  https://powerprojects.ai/api/v1/data-items/42/widgets/1/
response = requests.patch(
    f"{BASE_URL}/data-items/42/widgets/1/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"title": "Updated Title", "chart_type": "line"}
)
DELETE /api/v1/data-items/{id}/widgets/{widget_id}/

Delete a widget and all its series.

Widget Series

Series define the value aggregations displayed in a widget. Each series references a field and an aggregation function.

Aggregation functions: count, sum, avg, min, max, distinct_count
GET /api/v1/data-items/{id}/widgets/{widget_id}/series/

List all series for a widget.

200 Response
{
  "series": [
    {
      "id": 1,
      "value_field": 102,
      "aggregation": "sum",
      "label": "Total Revenue",
      "series_order": 0,
      "color": "#0052FF"
    }
  ]
}
POST /api/v1/data-items/{id}/widgets/{widget_id}/series/

Add a new series to a widget.

ParameterTypeDescription
value_fieldintegerrequiredField ID to aggregate
aggregationstringoptionalOne of: count, sum, avg, min, max, distinct_count. Default: sum
labelstringoptionalDisplay label for this series
series_orderintegeroptionalPosition in the series list
colorstringoptionalColor hex code or name (e.g. #0052FF)
curl -X POST \
  -H "X-Api-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"value_field": 103, "aggregation": "avg", "label": "Avg Cost", "color": "#FB923C"}' \
  https://powerprojects.ai/api/v1/data-items/42/widgets/1/series/
response = requests.post(
    f"{BASE_URL}/data-items/42/widgets/1/series/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "value_field": 103,
        "aggregation": "avg",
        "label": "Avg Cost",
        "color": "#FB923C"
    }
)
PATCH /api/v1/data-items/{id}/widgets/{widget_id}/series/{series_id}/

Update a series' value field, aggregation, label, order, or color. Only include the fields you want to change.

DELETE /api/v1/data-items/{id}/widgets/{widget_id}/series/{series_id}/

Remove a series from a widget.