---
# === IDENTITY ===
id: business/erp-integration/workday-prism-analytics-api/2026
canonical_question: "What are Workday Prism Analytics API capabilities - 256MB upload, 100GB total, 1000 fields per dataset?"
aliases:
  - "Workday Prism Analytics API limits and capabilities"
  - "Workday Prism data upload size limits and field constraints"
  - "How to load external data into Workday Prism Analytics via API"
  - "Workday Prism Analytics v3 REST API reference"
entity_type: erp_integration
domain: business > erp-integration > workday-prism-analytics-api
region: global
jurisdiction: global
temporal_scope: 2025-2026

# === SYSTEM PROFILE ===
systems:
  - name: "Workday Prism Analytics"
    vendor: "Workday"
    version: "API v3"
    edition: "Prism Analytics (included with Workday HCM/Financials)"
    deployment: "cloud"
    api_surface: "REST"

# === VERIFICATION ===
last_verified: 2026-03-02
confidence: 0.85
version: 1.0
first_published: 2026-03-02

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: evolving
  last_breaking_change: "API v3 replaced v2 datasets with SQL-style tables"
  next_review: 2026-08-29
  change_sensitivity: high

# === CONSTRAINTS ===
constraints:
  - "Max 256 MB per compressed file upload via Prism Data API"
  - "Max 100 GB total compressed data across all buckets per tenant"
  - "Max 1,000 fields (columns) per dataset/table"
  - "Max 32,000 characters per field value"
  - "Max 500,000 characters per row"
  - "Max 10 concurrent file uploads per bucket"
  - "Buckets expire after 24 hours — complete workflow must finish within that window"
  - "Files must be gzip-compressed, RFC 4180-compliant CSV"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "User needs Workday REST API for HCM/worker data (not analytics)"
    use_instead: "business/erp-integration/workday-rest-soap-api-capabilities/2026"
  - condition: "User needs Workday authentication setup (OAuth, ISU)"
    use_instead: "business/erp-integration/workday-authentication-isu-oauth/2026"
  - condition: "User needs Workday RaaS report-as-a-service integration"
    use_instead: "business/erp-integration/workday-raas-integration/2026"
  - condition: "User needs Workday Studio vs EIB comparison"
    use_instead: "business/erp-integration/workday-studio-eib-comparison/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: integration_pattern
    question: "What integration pattern do you need?"
    type: choice
    options:
      - "batch/bulk (scheduled external data loads into Prism)"
      - "file-based (CSV/gzip upload via API or SFTP)"
      - "programmatic table management (create, schema, upload, complete)"
  - key: data_volume
    question: "What's your data volume per load?"
    type: choice
    options:
      - "< 256 MB compressed (single file)"
      - "256 MB - 10 GB compressed (multi-file)"
      - "> 10 GB compressed (chunked multi-bucket strategy)"
  - key: direction
    question: "What's the data flow direction?"
    type: choice
    options:
      - "inbound (loading external data into Prism Analytics)"
      - "outbound (reading Prism datasets for downstream reporting)"
      - "bidirectional (external data in, blended reports out)"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/erp-integration/workday-prism-analytics-api/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-03-02)"

# === RELATED UNITS ===
related_kos:
  depends_on:
    - id: "business/erp-integration/workday-authentication-isu-oauth/2026"
      label: "Workday OAuth authentication setup (required for API access)"
  related_to:
    - id: "business/erp-integration/workday-rest-soap-api-capabilities/2026"
      label: "Workday REST/SOAP API for HCM and worker data"
    - id: "business/erp-integration/workday-raas-integration/2026"
      label: "Workday Report-as-a-Service for data extraction"
  alternative_to:
    - id: "business/erp-integration/workday-studio-eib-comparison/2026"
      label: "Workday Studio and EIB — alternative non-API integration tools"

# === SOURCES ===
sources:
  - id: src1
    title: "Workday Prism Analytics REST API v3 Reference (SimWorkflow)"
    author: SimWorkflow
    url: https://www.simworkflow.com/integration-operation/workday-prism-analytics-buckets-id-files-post-d9a
    type: technical_blog
    published: 2025-01-15
    reliability: high
  - id: src2
    title: "Workday Prism Analytics Connector — Boomi Documentation"
    author: Boomi
    url: https://help.boomi.com/docs/Atomsphere/Integration/Connectors/int-Workday_Prism_Analytics_V2_operation_1a61b100-c1b4-46bc-84af-352259a68843
    type: technical_blog
    published: 2025-06-01
    reliability: high
  - id: src3
    title: "Workday prism-python — Official Python Client Library"
    author: Workday
    url: https://github.com/Workday/prism-python
    type: official_docs
    published: 2025-03-01
    reliability: authoritative
  - id: src4
    title: "Workday REST API Integration and Security Guide"
    author: Reco.ai
    url: https://www.reco.ai/hub/workday-rest-api-integration-security
    type: technical_blog
    published: 2025-08-01
    reliability: moderate_high
  - id: src5
    title: "Workday Prism Analytics Implementation Considerations"
    author: Kognitiv Inc.
    url: https://kognitivinc.com/blog/workday-prism-analytics-implementation-considerations/
    type: community_resource
    published: 2024-09-01
    reliability: moderate_high
  - id: src6
    title: "Prism Analytics Overview — Stormloop"
    author: Stormloop Technologies
    url: https://www.stormlooptech.com/blog/prism-analytics-overview
    type: community_resource
    published: 2025-01-01
    reliability: moderate
  - id: src7
    title: "Rate Limiting in Workday Studio — Stephen Gilmore"
    author: Stephen Gilmore
    url: https://sglmr.com/blog/workday-studio-rate-limits/
    type: technical_blog
    published: 2024-11-01
    reliability: moderate_high
---

# Workday Prism Analytics API Capabilities & Limits

## TL;DR

- **Bottom line**: Workday Prism Analytics API v3 enables loading external data into SQL-style tables via a bucket-based upload workflow — create table, create bucket, upload gzip CSV files, complete bucket. All data must be gzip-compressed CSV.
- **Key limit**: 256 MB max per compressed file, 100 GB total across all buckets, 1,000 fields per dataset, and 10 concurrent uploads per bucket.
- **Watch out for**: Buckets expire after 24 hours — if your upload workflow takes longer, the bucket is lost and you must start over. Files must match the bucket schema exactly.
- **Best for**: Scheduled batch loads of external data (HR benchmarks, financial data, CRM exports) into Workday for blended analytics with native HCM/Finance data.
- **Authentication**: OAuth 2.0 refresh token flow — requires registered API Client with Client ID, Client Secret, and Refresh Token from Workday admin console.

## System Profile

Workday Prism Analytics is Workday's data hub for combining external data with native Workday HCM, Payroll, and Financial Management data. The Prism Analytics REST API (v3) provides programmatic access to create tables, define schemas, upload compressed CSV data through a bucket-based workflow, and manage data change tasks. API v3 introduced SQL-style tables, replacing the legacy v2 dataset model. Prism Analytics is included with Workday HCM and Financial Management subscriptions — there is no separate license required for the base Prism functionality, though advanced features (Data Hub, extended storage) may require additional licensing. [src5]

| Property | Value |
|---|---|
| **Vendor** | Workday |
| **System** | Workday Prism Analytics |
| **API Surface** | REST (HTTPS/JSON for metadata, HTTPS/gzip-CSV for data) |
| **Current API Version** | v3 |
| **Editions Covered** | All Workday tenants with Prism Analytics enabled |
| **Deployment** | Cloud (multi-tenant SaaS) |
| **API Docs URL** | [Workday Prism Python Client](https://github.com/Workday/prism-python) |
| **Status** | GA (v3 is current; v2 legacy/maintenance) |

## API Surfaces & Capabilities

| API Surface | Protocol | Best For | Max Per Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|
| Prism Analytics REST API v3 | HTTPS/JSON + gzip-CSV | External data loads into Prism tables | 256 MB compressed per file | Tenant-level throttling (429 with x-ratelimit-remaining header) | No | Yes |
| Workday REST API | HTTPS/JSON | HCM worker data, financial transactions | Paginated (100-1000 per page) | Tenant-level throttling | Yes | No |
| Workday SOAP API (WWS) | HTTPS/XML | Legacy integrations, metadata operations | Paginated | Shared with REST | Yes | No |
| RaaS (Report-as-a-Service) | HTTPS/CSV or JSON | Data extraction via custom reports | Full report output | Per-report timeout | No | Yes |
| EIB (Enterprise Interface Builder) | SFTP/file | Scheduled inbound/outbound file transfers | File-based | Scheduled | No | Yes |

## Rate Limits & Quotas

### Per-Request Limits

| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max file size per upload | 256 MB (compressed) | Prism Data API file upload | Files must be gzip-compressed CSV [src1, src2] |
| Max fields per table/dataset | 1,000 | Table schema definition | Applies to both base and derived datasets [src1] |
| Max field value length | 32,000 characters | Individual field values | Truncated if exceeded [src1] |
| Max row length | 500,000 characters | Single CSV row | Rows exceeding this are rejected [src1] |
| Max concurrent uploads | 10 | Per bucket | Parallel POST requests to same bucket [src1] |
| Files per POST request | 1 | Upload endpoint | Multiple files require multiple requests [src1] |

### Rolling / Daily Limits

| Limit Type | Value | Window | Edition Differences |
|---|---|---|---|
| Total storage across buckets | 100 GB (compressed) | Per tenant, cumulative | Applies to all active buckets across tenant [src2] |
| Bucket expiration | 24 hours | Per bucket lifecycle | Bucket and all uploaded files lost after expiration [src2] |
| API rate limiting | Tenant-level throttling | Rolling window | Returns 429 with x-ratelimit-remaining header [src7] |
| Published dataset storage | Tenant-configured | Per tenant | Contact Workday for tenant-specific limits [src5] |

## Authentication

| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 Refresh Token | All Prism API operations | Access token: session-based (typically 60 min) | Yes — use refresh token to obtain new access token | Recommended for all integrations [src3, src4] |
| OAuth 2.0 Client Credentials | Server-to-server (ISU-based) | Access token: session-based | No refresh token — new token per request | Requires Integration System User (ISU) [src4] |

### Authentication Gotchas

- Workday OAuth requires a registered API Client under Tenant Setup — you need Client ID, Client Secret, AND a Refresh Token (three separate credentials, not two). The Refresh Token is generated per ISU (Integration System User) and must be regenerated if the ISU password changes. [src3]
- Token endpoint URL is tenant-specific: `https://{hostname}/ccx/oauth2/{tenant}/token`. Using the wrong tenant name or hostname (e.g., mixing impl vs prod) silently returns 401. [src4]
- Access tokens are scoped to the ISU's security profile — the Prism API requires six specific security domains: Tables Manage, Tables Owner Manage, Delete Table Data, Insert Table Data, Truncate Table Data, Update Table Data. Missing any one domain causes 403 errors on specific operations. [src1]
- Refresh tokens do not expire by default but CAN be revoked by Workday admins. Build monitoring for 401 responses and alert on refresh token failures. [src3]

## Constraints
<!-- Agents: read this section before recommending any integration approach from this unit.
     These are hard constraints that must not be violated. -->

- **256 MB compressed file limit**: Individual file uploads cannot exceed 256 MB after gzip compression. For larger datasets, split into multiple files and upload to the same bucket. [src1, src2]
- **100 GB tenant storage cap**: Total compressed data across ALL active buckets cannot exceed 100 GB. Old buckets must be completed or expired before new large loads. [src2]
- **1,000 field maximum**: Tables and datasets cannot have more than 1,000 fields (columns). Wide denormalized schemas must be split into multiple related tables. [src1]
- **24-hour bucket expiration**: Buckets in "New" state expire after exactly 24 hours. All file uploads AND the Complete Bucket call must finish within this window. [src2]
- **gzip CSV only**: The Prism Data API only accepts gzip-compressed, RFC 4180-compliant delimited files. No JSON, Parquet, or uncompressed uploads. [src1]
- **Schema must match exactly**: Uploaded file schema must match the bucket's defined schema. Column order, types, and names must align — there is no automatic type coercion or column reordering. [src1]
- **10 concurrent uploads max**: No more than 10 simultaneous file upload POST requests per bucket. Additional requests are rejected. [src1]

## Integration Pattern Decision Tree

```
START — User needs to load external data into Workday Prism Analytics
├── Data size per load?
│   ├── < 256 MB compressed
│   │   ├── Single file upload to bucket → simplest workflow
│   │   └── Schema already exists?
│   │       ├── YES → Create bucket on existing table → upload → complete
│   │       └── NO → Create table with schema → create bucket → upload → complete
│   ├── 256 MB - 100 GB compressed
│   │   ├── Split into files ≤ 256 MB each
│   │   ├── Upload up to 10 files concurrently per bucket
│   │   └── Monitor bucket expiration (24h window)
│   └── > 100 GB compressed
│       ├── STOP — exceeds tenant storage cap
│       ├── Request storage increase from Workday
│       └── Or: load in rolling batches (load → complete → load next batch)
├── How often?
│   ├── One-time migration → Prism API with manual orchestration
│   ├── Daily/weekly scheduled → iPaaS (Boomi, SnapLogic, Jitterbit) or Workday Studio
│   └── Near-real-time → NOT recommended for Prism (use Workday REST API for transactional data)
├── Data change operation?
│   ├── Full refresh → TruncateAndInsert (drops existing data, loads new)
│   ├── Append new records → Insert
│   ├── Update existing by key → Update or Upsert
│   └── Remove records → Delete
└── Integration platform?
    ├── Custom code → prism-python library or direct REST API calls
    ├── iPaaS → Boomi, SnapLogic, Jitterbit, Workato (all have native Prism connectors)
    └── Workday-native → Workday Studio + EIB (for file-based loads)
```

## Quick Reference

### Prism Analytics API v3 Endpoint Reference

| Operation | Method | Endpoint | Payload | Notes |
|---|---|---|---|---|
| List tables | GET | /api/prismAnalytics/v3/{tenant}/tables | N/A | Returns all Prism tables visible to ISU [src3] |
| Create table | POST | /api/prismAnalytics/v3/{tenant}/tables | JSON schema | Defines table name, fields, types [src3] |
| Get table | GET | /api/prismAnalytics/v3/{tenant}/tables/{id} | N/A | Returns schema and metadata [src3] |
| Create bucket | POST | /api/prismAnalytics/v3/{tenant}/tables/{id}/buckets | JSON config | Specifies operation (Insert, Upsert, etc.) [src1, src2] |
| Upload file | POST | /api/prismAnalytics/v3/{tenant}/buckets/{id}/files | gzip CSV (binary) | One file per request, max 256 MB [src1] |
| Complete bucket | POST | /api/prismAnalytics/v3/{tenant}/buckets/{id}/complete | N/A | Triggers data processing into table [src2] |
| Get bucket status | GET | /api/prismAnalytics/v3/{tenant}/buckets/{id} | N/A | Check processing status [src2] |
| Delete table data | POST | /api/prismAnalytics/v3/{tenant}/tables/{id}/dataChanges | JSON | Data change task with Delete operation [src3] |

### Table Operations

| Operation | Behavior | Use When |
|---|---|---|
| TruncateAndInsert | Deletes all existing rows, inserts new data | Full refresh / daily reload [src3] |
| Insert | Appends new rows (no dedup) | Adding net-new records [src3] |
| Update | Updates existing rows by primary key | Modifying existing records [src3] |
| Upsert | Inserts new rows, updates existing by key | Mixed new + updated records [src3] |
| Delete | Removes rows matching criteria | Data cleanup / GDPR compliance [src3] |

## Step-by-Step Integration Guide

### 1. Register API Client and Obtain Credentials

Navigate to Workday Tenant Setup > API Clients for Integrations. Register a new API Client, note the Client ID and Client Secret. Create an ISU with the required Prism security domains, then generate a Refresh Token for that ISU. [src3, src4]

```bash
# Test OAuth token retrieval
curl -X POST "https://{hostname}/ccx/oauth2/{tenant}/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=refresh_token&refresh_token={refresh_token}"
```

**Verify**: Response contains `access_token` and `token_type: "Bearer"`.

### 2. Create a Prism Table with Schema

Define your table schema as JSON with field names, types, and ordinals. POST it to the tables endpoint. [src3]

```bash
curl -X POST "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "External_Sales_Data",
    "displayName": "External Sales Data",
    "fields": [
      {"name": "sale_id", "ordinal": 1, "type": {"id": "f9e5bff9c4fb4a05a0fea0b5ba541da7"}, "precision": 0, "scale": 0},
      {"name": "sale_date", "ordinal": 2, "type": {"id": "bdd201eb21954fbfa14ab8e6b5ab83a9"}},
      {"name": "amount", "ordinal": 3, "type": {"id": "48fbad81ffdb41e5863ea5e699e7d3f6"}, "precision": 18, "scale": 2},
      {"name": "region", "ordinal": 4, "type": {"id": "f9e5bff9c4fb4a05a0fea0b5ba541da7"}}
    ]
  }'
```

**Verify**: Response includes `"id"` for the new table. Save this table ID.

### 3. Create a Bucket for Data Upload

Create a bucket on the table specifying the data change operation. [src1, src2]

```bash
curl -X POST "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables/{table_id}/buckets" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "daily_load_20260302",
    "operation": { "id": "TruncateAndInsert" }
  }'
```

**Verify**: Response includes bucket `"id"` with `"state": "New"`. Note: bucket expires in 24 hours.

### 4. Upload Gzip-Compressed CSV File(s)

Compress your CSV data with gzip, then upload. The file schema must match the table schema exactly. [src1]

```bash
# Compress the CSV file
gzip -k sales_data.csv

# Upload to bucket (one file per request, max 256 MB compressed)
curl -X POST "https://{hostname}/api/prismAnalytics/v3/{tenant}/buckets/{bucket_id}/files" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/octet-stream" \
  -H "Content-Disposition: attachment; filename=sales_data.csv.gz" \
  --data-binary @sales_data.csv.gz
```

**Verify**: HTTP 200 response. For multiple files, repeat (up to 10 concurrent uploads).

### 5. Complete the Bucket

Signal that all files have been uploaded. This triggers Prism to process the data into the table. [src2]

```bash
curl -X POST "https://{hostname}/api/prismAnalytics/v3/{tenant}/buckets/{bucket_id}/complete" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json"
```

**Verify**: Poll bucket status endpoint until `"state": "Success"`. Processing time depends on data volume.

### 6. Verify Data in Prism Table

Check the table to confirm rows were loaded. [src3]

```bash
curl -X GET "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables/{table_id}" \
  -H "Authorization: Bearer {access_token}"
```

**Verify**: Response shows updated `rowCount` matching expected record count.

## Code Examples

### Python: Load External Data into Prism Table Using Official Client

```python
# Input:  CSV file path, Workday credentials
# Output: Table ID, upload status, row count

# pip install git+https://github.com/Workday/prism-python.git
import prism

# Initialize Prism client (OAuth handled internally)
p = prism.Prism(
    base_url="https://wd2-impl-services1.workday.com",
    tenant_name="your_tenant",
    client_id="your_client_id",
    client_secret="your_client_secret",
    refresh_token="your_refresh_token"
)

# Create table from schema file (first time only)
table = prism.tables_create(
    p,
    table_name="External_Sales_Data",
    file="/path/to/schema.json"  # JSON schema definition
)
print(f"Table created: {table['id']}")

# Upload gzip CSV data (handles bucket creation + completion)
prism.upload_file(
    p,
    file="/path/to/sales_data.csv.gz",  # Must be gzip compressed
    table_id=table["id"],
    operation="TruncateAndInsert"  # Or: Insert, Update, Upsert, Delete
)
print("Upload complete — check Prism for data")
```
[src3]

### Python: Direct REST API Upload (No Client Library)

```python
# Input:  CSV file path, Workday credentials
# Output: Table ID, bucket status

import requests
import gzip
import json

BASE = "https://{hostname}/api/prismAnalytics/v3/{tenant}"

# Step 1: Get OAuth token
token_resp = requests.post(
    "https://{hostname}/ccx/oauth2/{tenant}/token",
    auth=("client_id", "client_secret"),
    data={"grant_type": "refresh_token", "refresh_token": "your_token"}
)
access_token = token_resp.json()["access_token"]
headers = {"Authorization": f"Bearer {access_token}"}

# Step 2: Create bucket on existing table
bucket_resp = requests.post(
    f"{BASE}/tables/{table_id}/buckets",
    headers={**headers, "Content-Type": "application/json"},
    json={"name": "load_20260302", "operation": {"id": "TruncateAndInsert"}}
)
bucket_id = bucket_resp.json()["id"]

# Step 3: Upload gzip file (max 256 MB)
with open("sales_data.csv.gz", "rb") as f:
    upload_resp = requests.post(
        f"{BASE}/buckets/{bucket_id}/files",
        headers={**headers, "Content-Type": "application/octet-stream"},
        data=f
    )

# Step 4: Complete bucket
complete_resp = requests.post(
    f"{BASE}/buckets/{bucket_id}/complete",
    headers=headers
)
print(f"Bucket status: {complete_resp.json().get('state')}")
```
[src1, src4]

### cURL: Quick API Test — List All Prism Tables

```bash
# Input:  Valid access token
# Output: JSON array of Prism Analytics tables

# Get token
TOKEN=$(curl -s -X POST "https://{hostname}/ccx/oauth2/{tenant}/token" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=refresh_token&refresh_token={refresh_token}" | jq -r '.access_token')

# List all tables
curl -s "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables" \
  -H "Authorization: Bearer $TOKEN" | jq '.data[] | {id, name, displayName}'
```
[src3]

## Data Mapping

### Prism Analytics Field Type Reference

| Prism Type ID | Type Name | Source Format | Gotcha |
|---|---|---|---|
| f9e5bff9c4fb4a05a0fea0b5ba541da7 | Text | String (max 32,000 chars) | Exceeding 32K chars silently truncates [src1] |
| 48fbad81ffdb41e5863ea5e699e7d3f6 | Numeric | Decimal (precision + scale) | Precision/scale mismatch causes load failure [src1] |
| bdd201eb21954fbfa14ab8e6b5ab83a9 | Date | ISO 8601 (YYYY-MM-DD) | Workday only accepts specific date formats — non-ISO dates rejected [src1] |
| d6cce1d0962b4bd0abb48382bbc4d3c9 | Boolean | true/false | Must be lowercase — "True" or "1" are rejected [src1] |
| 1f01ef53c87d42b0b0aab7eafc2b7a60 | Instance | Workday WID reference | Must match existing Workday reference data [src1] |

### Data Type Gotchas

- Prism field type IDs are WID-style UUIDs, not human-readable names. You must use the exact UUID for each type in your schema JSON. Incorrect type IDs cause cryptic "invalid field type" errors. [src1]
- Numeric fields require explicit precision and scale in the schema. A field defined as precision=18, scale=2 will reject values with more than 2 decimal places. [src1]
- Date fields must match one of Workday's supported date formats. The safest is ISO 8601 (YYYY-MM-DD). Timestamps with timezone offsets may be silently truncated to date-only. [src1]
- CSV encoding must be UTF-8. BOM (Byte Order Mark) characters at the start of files can cause the first field name to be misread, failing schema validation. [src2]

## Error Handling & Failure Points

### Common Error Codes

| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 401 Unauthorized | Invalid or expired token | Access token expired or refresh token revoked | Re-authenticate with refresh token; if 401 persists, regenerate refresh token in Workday admin [src4] |
| 403 Forbidden | Insufficient security permissions | ISU missing required Prism security domains | Add all 6 Prism security domains to ISU security profile [src1] |
| 404 Not Found | Table or bucket does not exist | Wrong table/bucket ID, or bucket expired (24h) | Verify IDs; if bucket expired, create a new one [src2] |
| 409 Conflict | Bucket state conflict | Attempting upload on completed/expired bucket | Create a new bucket — buckets are single-use [src2] |
| 413 Payload Too Large | File exceeds 256 MB | Uploaded file too large (compressed) | Split file into chunks < 256 MB each [src1] |
| 429 Too Many Requests | Rate limit exceeded | Too many API calls in rolling window | Read x-ratelimit-remaining header, implement exponential backoff [src7] |
| 422 Unprocessable Entity | Schema mismatch | CSV columns don't match table schema | Verify column names, order, and types match exactly [src1] |

### Failure Points in Production

- **Bucket expiration mid-upload**: Large multi-file uploads that take >24 hours lose the bucket and all uploaded files. Fix: `Monitor elapsed time; if approaching 24h, complete what's uploaded and start a new bucket for remaining files.` [src2]
- **Schema drift between loads**: Source system adds/removes columns between scheduled loads, causing schema mismatch. Fix: `Validate CSV headers against table schema before uploading; implement schema version checking in your pipeline.` [src1]
- **Silent field truncation**: Text fields exceeding 32,000 characters are silently truncated without error, causing data loss. Fix: `Pre-validate field lengths in ETL pipeline; add length assertions.` [src1]
- **Refresh token revocation**: Workday admin resets ISU password or revokes token, breaking unattended integrations. Fix: `Monitor for 401 errors on token refresh; alert immediately; store backup refresh token.` [src3]
- **Concurrent upload rejection**: Exceeding 10 concurrent uploads per bucket returns errors on the 11th request. Fix: `Implement upload queue with max 10 parallel workers; use semaphore pattern.` [src1]
- **gzip compression failures**: Some compression libraries produce non-standard gzip that Workday rejects. Fix: `Use standard gzip (not zip, not bzip2); test with Python's gzip module or command-line gzip.` [src2]

## Anti-Patterns

### Wrong: Uploading uncompressed CSV directly

```python
# BAD — Prism API only accepts gzip-compressed files
with open("data.csv", "rb") as f:
    requests.post(f"{BASE}/buckets/{bucket_id}/files",
                  headers=headers, data=f)  # Will fail: not gzip
```

### Correct: Always gzip-compress before upload

```python
# GOOD — Compress CSV before uploading
import gzip
import shutil

with open("data.csv", "rb") as f_in:
    with gzip.open("data.csv.gz", "wb") as f_out:
        shutil.copyfileobj(f_in, f_out)

with open("data.csv.gz", "rb") as f:
    requests.post(f"{BASE}/buckets/{bucket_id}/files",
                  headers={**headers, "Content-Type": "application/octet-stream"},
                  data=f)
```

### Wrong: Loading >256 MB as a single file

```python
# BAD — Single file exceeds 256 MB limit
# Entire upload fails with 413
with open("huge_dataset.csv.gz", "rb") as f:  # 500 MB compressed
    requests.post(f"{BASE}/buckets/{bucket_id}/files",
                  headers=headers, data=f)
```

### Correct: Split large datasets into chunks < 256 MB

```python
# GOOD — Split into multiple files, upload concurrently (max 10)
import os
import concurrent.futures

CHUNK_SIZE = 200 * 1024 * 1024  # 200 MB chunks (under 256 MB limit)

def upload_chunk(chunk_path, bucket_id):
    with open(chunk_path, "rb") as f:
        return requests.post(
            f"{BASE}/buckets/{bucket_id}/files",
            headers={**headers, "Content-Type": "application/octet-stream"},
            data=f
        )

# Upload up to 10 files concurrently
chunks = [f for f in os.listdir("chunks/") if f.endswith(".csv.gz")]
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as pool:
    futures = [pool.submit(upload_chunk, f"chunks/{c}", bucket_id) for c in chunks]
    for future in concurrent.futures.as_completed(futures):
        print(f"Upload status: {future.result().status_code}")
```

### Wrong: Reusing expired buckets

```python
# BAD — Bucket created yesterday, now expired
# Returns 404 or 409
requests.post(f"{BASE}/buckets/{old_bucket_id}/files",
              headers=headers, data=data)
```

### Correct: Always create a fresh bucket per load cycle

```python
# GOOD — Create new bucket for each data load
bucket_resp = requests.post(
    f"{BASE}/tables/{table_id}/buckets",
    headers={**headers, "Content-Type": "application/json"},
    json={"name": f"load_{datetime.now().strftime('%Y%m%d_%H%M')}",
          "operation": {"id": "TruncateAndInsert"}}
)
bucket_id = bucket_resp.json()["id"]
# Upload immediately — 24h clock starts now
```

## Common Pitfalls

- **Assuming JSON upload support**: Prism Data API only accepts gzip-compressed CSV. There is no JSON, Parquet, or raw CSV upload path. Many developers waste time trying JSON payloads. Fix: `Always gzip-compress RFC 4180-compliant CSV files.` [src1]
- **Ignoring the 24-hour bucket window**: Developers create buckets in advance during testing, then find them expired in production. Fix: `Create buckets immediately before uploading; add timestamp checks in your pipeline.` [src2]
- **Not validating schema before upload**: Column mismatches between CSV and table schema cause the entire bucket to fail on completion. Fix: `Compare CSV headers against table schema endpoint response before starting upload.` [src1]
- **Hardcoding type UUIDs**: Prism field type IDs are WIDs that could theoretically change. Fix: `Retrieve type definitions dynamically via the API, or maintain a version-pinned mapping with your schema.` [src1]
- **Forgetting ISU security domains**: A partial set of Prism security domains causes some operations to work (e.g., read) while others fail (e.g., write). Fix: `Grant all 6 Prism security domains: Tables Manage, Tables Owner Manage, Delete Table Data, Insert Table Data, Truncate Table Data, Update Table Data.` [src1]
- **Not monitoring x-ratelimit-remaining**: Workday's rate limiting is tenant-level and not well-documented. Hitting limits causes 429 errors that can cascade. Fix: `Read x-ratelimit-remaining header on every response; pause when value drops below 25.` [src7]

## Diagnostic Commands

```bash
# Test OAuth authentication
curl -s -X POST "https://{hostname}/ccx/oauth2/{tenant}/token" \
  -u "{client_id}:{client_secret}" \
  -d "grant_type=refresh_token&refresh_token={refresh_token}" | jq '.access_token'

# List all Prism tables (verify API access)
curl -s "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables" \
  -H "Authorization: Bearer {token}" | jq '.total'

# Check specific table schema
curl -s "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables/{table_id}" \
  -H "Authorization: Bearer {token}" | jq '.fields'

# Check bucket status (after upload)
curl -s "https://{hostname}/api/prismAnalytics/v3/{tenant}/buckets/{bucket_id}" \
  -H "Authorization: Bearer {token}" | jq '{state, fileCount, errorMessage}'

# Monitor rate limit headers
curl -sv "https://{hostname}/api/prismAnalytics/v3/{tenant}/tables" \
  -H "Authorization: Bearer {token}" 2>&1 | grep -i 'x-ratelimit'
```

## Version History & Compatibility

| API Version | Release Date | Status | Breaking Changes | Migration Notes |
|---|---|---|---|---|
| v3 | 2023 (GA) | Current | SQL-style tables replace datasets; new endpoint paths | Migrate from /datasets to /tables; schema format changed [src3] |
| v2 | 2020 | Maintenance/Legacy | N/A (original GA) | Still functional but new features only in v3 [src2] |
| v1 | 2018 | Deprecated | N/A | Do not use; no longer supported |

### Deprecation Policy

Workday follows a biannual release cycle (R1 and R2). API changes are communicated through Workday Community release notes. Workday does not formally publish a fixed deprecation timeline for Prism API versions, but v2 endpoints continue to function in maintenance mode while all new features target v3. Integrators should plan migration to v3 for all new development. [src3]

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Loading external data (CRM, ERP, benchmarks) into Workday for blended analytics | Need real-time transactional data integration | Workday REST API for worker/financial transactions |
| Scheduled batch data loads (daily, weekly) | Need sub-second latency for individual record operations | Workday REST API or SOAP API |
| Building composite dashboards combining Workday + external data | Need to extract data FROM Workday | RaaS (Report-as-a-Service) or Workday REST API |
| Data migration or one-time bulk loads | Dataset has >1,000 columns | Restructure schema; split into multiple related tables |
| Replacing manual browser file uploads with automated API loads | Data volume exceeds 100 GB compressed per tenant | Contact Workday for storage increase or implement rolling batch strategy |

## Important Caveats

- Prism Analytics limits are not prominently documented by Workday — most limit values come from iPaaS connector documentation (Boomi, SnapLogic) and the official Python client library rather than the API reference itself. Always verify against your tenant's actual behavior.
- The 100 GB storage limit is across ALL active buckets — completing or letting buckets expire frees up space. Plan your load schedule to avoid hitting this ceiling.
- Prism Analytics is optimized for Workday-native data blending. Complex transformations on external data should be done BEFORE loading into Prism, not within Prism's transformation layer.
- Workday's rate limiting varies by tenant and is not publicly documented with specific numbers. The x-ratelimit-remaining header is the only reliable indicator — build your integration to be rate-limit-aware from day one.
- Field type UUIDs (WIDs) used in schema definitions appear stable but are not guaranteed across Workday releases. Pin your schema definitions and test after each Workday release upgrade.

## Related Units
<!-- Generated from related_kos frontmatter -->

- [Workday OAuth Authentication Setup](/business/erp-integration/workday-authentication-isu-oauth/2026)
- [Workday REST/SOAP API Capabilities](/business/erp-integration/workday-rest-soap-api-capabilities/2026)
- [Workday RaaS Integration](/business/erp-integration/workday-raas-integration/2026)
- [Workday Studio vs EIB Comparison](/business/erp-integration/workday-studio-eib-comparison/2026)
