Guide to Workday Financial Management: Ledger Accounts, Journal Entries, and Expenses

Introduction

Workday Financial Management uses Accounting Journals as the primary mechanism for recording all financial transactions. Unlike some accounting systems that have dedicated "Expense" objects, Workday treats expenses as a specialized type of journal entry. Before working with transactions, you need to understand Workday's Ledger Account structure with its Account Sets and hierarchies.

Apideck's unified Accounting API abstracts these complexities by offering three interconnected resources:

  • Ledger Accounts: The chart of accounts organized by Account Sets (Corporate, GAAP, IFRS, etc.)
  • Journal Entries: Full control over debit/credit transactions for any accounting operation
  • Expenses: Streamlined interface for recording already-paid purchases

This guide provides comprehensive coverage of all three resources, explaining how to retrieve account structures, create financial transactions, manage approval workflows, and handle Workday's unique features like Account Sets and Worktags.

Common Background

Workday's Journal Architecture

In Workday, financial transactions are recorded as Journal Entries. Each journal entry contains:

  • Header Information: Company, currency, accounting date, memo, journal source
  • Journal Entry Lines: Individual debit and credit lines with ledger accounts
  • Worktags: Workday's flexible tagging system for tracking categories (cost centers, projects, spend categories, etc.)
  • Status Information: Tracking workflow state from draft through posting

Workday processes journal entries individually. Each entry can be submitted, approved, and posted through its own workflow without affecting other entries.

Account Sets and Encoded IDs

Workday uses a hierarchical Account Set structure for ledger accounts. Each ledger account belongs to an Account Set (like "Corporate", "GAAP", or "Tax"), allowing multiple accounting frameworks in one system.

Apideck's Account ID Format:

// Workday ledger account ID is base64-encoded JSON
{
  "Account_Id": "6400",
  "Account_Set_Id": "Corporate"
}
// Encoded: "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="

This encoding ensures account references work correctly across Workday's multi-dimensional accounting structure.

Apideck's Unified Model

Apideck provides a simplified interface for working with Workday's complex SOAP-based financial APIs:

  • Journal Entries: Full control over all debit and credit lines, suitable for any type of accounting transaction
  • Expenses: Streamlined interface for "already paid" purchases where you specify expense lines and Apideck generates balancing payment line

Both map to Workday's Submit_Accounting_Journal SOAP operation but present different developer experiences:

  • Journal Entries require explicit debit/credit balance
  • Expenses automatically create offsetting payment line from the account field

I. Ledger Accounts

Problem Overview

Workday's chart of accounts uses a sophisticated Account Set architecture that supports multiple accounting frameworks simultaneously (Corporate, GAAP, IFRS, Tax, etc.). This means a single ledger account like "Professional Fees" isn't uniquely identified by just its account number – you must specify both the Account_Id and the Account_Set_Id.

Working directly with Workday's SOAP APIs for ledger accounts presents challenges:

  • Multi-ID System: Accounts have WIDs, Account_IDs, Account_Set_IDs, and parent references
  • Account Set Hierarchy: Each account belongs to a specific accounting framework
  • Complex XML Structures: SOAP responses contain deeply nested XML with multiple reference types
  • Parent-Child Relationships: Accounts form hierarchies within Account Sets
  • Status and Type Management: Active/inactive accounts, various account types (asset, liability, expense, etc.)

Apideck's connector solves this by:

  • Encoding Account_Id + Account_Set_Id into a single base64-encoded ID
  • Flattening hierarchical structures into simple JSON
  • Automatically handling Account Set references in transactions

Retrieving Ledger Accounts

Get All Ledger Accounts

GET /accounting/ledger-accounts retrieves the complete chart of accounts with Account Set information.

Example Request:

GET /accounting/ledger-accounts
x-apideck-app-id: your-app-id
x-apideck-service-id: workday

Example Response:

{
  "status_code": 200,
  "data": [
    {
      "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0=",
      "display_id": "6400",
      "classification": "expense",
      "name": "Professional Fees",
      "active": true,
      "status": "active",
      "parent_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjAwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0=",
        "name": "Operating Expenses",
      }
    }
  ],
  "meta": {
    "items_on_page": 1,
    "cursors": {
      "previous": null,
      "current": "page=1",
      "next": "page=2"
    }
  }
}

Key Response Fields

Identity Fields:

  • id: Base64-encoded JSON containing Account_Id and Account_Set_Id
  • display_id: Human-readable ledger account account number

Classification:

  • classification: High-level type (asset, liability, equity, revenue, expense)

Hierarchy:

  • parent_account: Parent account details in the hierarchy

Status:

  • active: Whether account is active
  • status: Account status (active, inactive)

Get One Ledger Account

GET /accounting/ledger-accounts/{id} retrieves a specific account by its encoded ID.

Example Request:

GET /accounting/ledger-accounts/eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0=
x-apideck-service-id: workday

Response: Single account object with same structure as shown above.

Understanding the Encoded Account ID

Decoding the ID Structure

Apideck encodes Workday's two-part account reference into a single ID:

Encoded Format:

eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0=

Decoded JSON:

{
  "Account_Id": "6400",
  "Account_Set_Id": "Corporate"
}

Why Encoding is Necessary

Workday's SOAP API requires both pieces of information to uniquely identify an account:

Workday XML Structure:

<wd:Ledger_Account_Reference>
  <wd:ID wd:type="Ledger_Account_ID" 
         wd:parent_type="Account_Set_ID" 
         wd:parent_id="Corporate">6400</wd:ID>
</wd:Ledger_Account_Reference>

Why both are needed:

  • Account "6400" might exist in multiple Account Sets (Corporate, GAAP, IFRS)
  • Each Account Set represents a different accounting framework
  • The same account number can have different configurations per framework

Using Encoded IDs in Transactions

When creating journal entries or expenses, use the full encoded ID:

{
  "line_items": [
    {
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    }
  ]
}

Apideck automatically:

  1. Decodes the base64 ID
  2. Extracts Account_Id and Account_Set_Id
  3. Constructs proper Workday XML references
  4. Validates the account exists and is active

II. Journal Entries

Problem Overview

Workday's Financial Management uses Accounting Journals as the universal mechanism for recording financial transactions. However, working directly with Workday's SOAP APIs presents several challenges:

  • SOAP Complexity: Workday uses SOAP/XML for financial operations, requiring complex XML request construction
  • Account Set Hierarchy: Ledger accounts exist within Account Sets, requiring both Account_Id and Account_Set_Id for proper references
  • Multi-ID System: Every Workday object has multiple IDs (WID, reference IDs, display IDs) requiring careful handling
  • Worktags Complexity: Flexible tagging system with type-specific IDs and parent relationships
  • Status Workflow: Six distinct status states with specific transitions between them

Apideck's connector abstracts these complexities by providing a unified Journal Entry model that handles SOAP envelope construction, account encoding, worktag mapping, and status translation automatically.

Initial Setup

Before using journal entry operations, you need to configure your Workday connection in Apideck:

Workday API Access

Please refer to this guide - https://developers.apideck.com/connectors/workday/docs/consumer+connection

Adding Journal Entries (Create)

When you add a journal entry via Apideck, you are creating an Accounting Journal in Workday via the Submit_Accounting_Journal SOAP operation.

Key Aspects

  • Unified journal entry model: Apideck provides a simplified JSON model that maps to Workday's complex XML structure
  • Status control at creation: Set status: draft to save without submitting, or status: posted to submit and post immediately
  • Automatic balancing validation: Workday enforces debit/credit balance. Entries will fail submission if debits don't equal credits
  • Worktags support: Map tracking_categories to Workday's flexible worktag system (cost centers, projects, spend categories)
  • Account encoding: Apideck handles the base64 encoding of Account_Id + Account_Set_Id structures
  • Immutable after posting: Once status: posted, the entry becomes part of the general ledger and cannot be modified

Workday-Specific Fields

{
  "number": "JE-2025-001",           // Journal number (reference)
  "status": "draft",                 // draft | pending_approval | approved | posted
  "posted_at": "2025-01-15",         // Accounting date
  "currency": "USD",                 // Currency code
  "company_id": "Global_Modern_Services_Inc_USA",  // Organization_Reference_ID
  "memo": "Q1 Adjusting Entry",      // Journal memo
  "source_type": "Manual_Journal",   // Journal source (Manual_Journal, System, etc.)
  "line_items": [                    // Must balance (total debits = total credits)
    {
      "type": "debit",              // "debit" or "credit"
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="  // Base64 encoded
      },
      "tracking_categories": [      // Workday Worktags
        {
          "parent_id": "Spend_Category_ID",
          "id": "Legal_and_Auditing_Fees"
        },
        {
          "parent_id": "Cost_Center_Reference_ID",
          "id": "50000_Office_of_CFO"
        }
      ]
    },
    {
      "type": "credit",
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiMjA1MCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      },
      "tracking_categories": [
        {
          "parent_id": "Spend_Category_ID",
          "id": "Legal_and_Auditing_Fees"
        },
        {
          "parent_id": "Cost_Center_Reference_ID",
          "id": "50000_Office_of_CFO"
        }
      ]
    }
  ]
}

Creating a Draft Journal Entry

Request to Apideck:

POST /accounting/journal-entries
Content-Type: application/json
x-apideck-app-id: your-app-id
x-apideck-service-id: workday

{
  "number": "JE-2025-001",
  "status": "draft",
  "posted_at": "2025-01-15",
  "currency": "USD",
  "company_id": "Global_Modern_Services_Inc_USA",
  "memo": "Q1 Adjusting Entry",
  "source_type": "Manual_Journal",
  "line_items": [
    {
      "type": "debit",
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    },
    {
      "type": "credit",
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiMjA1MCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    }
  ]
}

What Happens:

  1. Apideck constructs SOAP XML envelope with authentication
  2. Sends Submit_Accounting_Journal SOAP request to Workday
  3. Returns unified response with Workday WID as the id

Response:

{
  "status_code": 200,
  "status": "OK",
  "service": "workday",
  "resource": "journal-entries",
  "operation": "add",
  "data": {
    "id": "a10dee2ca7258147170cb396fe154022"  // Workday WID
  }
}

Creating and Posting in One Step

To create and immediately post a journal entry, set status: posted:

{
  "number": "JE-2025-002",
  "status": "posted",           // ← Will submit AND post
  "posted_at": "2025-01-15",
  "currency": "USD",
  "company_id": "Global_Modern_Services_Inc_USA",
  "memo": "Monthly Depreciation",
  "line_items": [
    {
      "description": "Depreciation Expense",
      "type": "debit",
      "total_amount": 2500.00,
      "ledger_account": { "id": "{encoded-account-id}" },
      "tracking_categories": [
       {
       "id": "",
       "parent_id": ""
       }
      ]
    },
    {
      "description": "Accumulated Depreciation",
      "type": "credit",
      "total_amount": 2500.00,
      "ledger_account": { "id": "{encoded-account-id}" },
      "tracking_categories": [
       {
       "id": "",
       "parent_id": ""
       }
      ]
    }
  ]
}

Updating a Journal Entry

Journal entries can only be updated while in draft status. Once submitted for approval or posted, Workday treats them as immutable.

Update Request:

PATCH /accounting/journal-entries/{id}
Content-Type: application/json

{
  "memo": "Updated memo text",
  "line_items": [
    {
      "description": "Updated line description",
      "type": "debit",
      "total_amount": 6000.00,
      "ledger_account": { "id": "{encoded-account-id}" },
      "tracking_categories": [
       {
       "id": "",
       "parent_id": ""
       }
      ]
    },
    {
      "description": "Updated credit line",
      "type": "credit",
      "total_amount": 6000.00,
      "ledger_account": { "id": "{encoded-account-id}" },
      "tracking_categories": [
       {
       "id": "",
       "parent_id": ""
       }
      ]
    }
  ]
}

Important Limitations:

  • Can update: Draft status entries
  • Cannot update: Submitted, approved, or posted entries
  • ⚠️ Line replacement: Update replaces ALL lines, not just modified ones

Important Notes:

  • Auto_Complete behavior: Determined by Workday configuration. Some tenants allow auto-posting for API-created journals, others require manual approval
  • Approval workflows: Workday may route journals to approvers based on amount thresholds, cost centers, or other business rules
  • No rollback: Once posted, journal entries are permanent and read-only.
  • Individual Processing: Workday posts each journal individually – no risk of accidentally posting other unrelated entries

Retrieving Journal Entries (Get One / Get All)

Get One Journal Entry

GET /accounting/journal-entries/{id} retrieves a single journal entry by its Workday WID.

Example Request:

GET /accounting/journal-entries/a10dee2ca7258147170cb396fe154022
x-apideck-app-id: your-app-id
x-apideck-service-id: workday

Example Response:

{
  "status_code": 200,
  "data": {
    "id": "a10dee2ca7258147170cb396fe154022",
    "number": "10783",
    "status": "posted",
    "posted_at": "2021-06-30T00:00:00Z",
    "currency": "USD",
    "company_id": "Global_Modern_Services_Inc_USA",
    "memo": "Q2 Audit Accrual",
    "source_type": "Manual_Journal",
    "line_items": [
      {
        "line_number": 1,
        "description": "Q2 Audit Accrual",
        "type": "debit",
        "total_amount": 60000,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories": [
          {
            "parent_id": "Spend_Category_ID",
            "id": "Legal_and_Auditing_Fees"
          },
          {
            "parent_id": "Cost_Center_Reference_ID",
            "id": "50000_Office_of_CFO"
          }
        ]
      },
      {
        "line_number": 2,
        "description": "Q2 Audit Accrual",
        "type": "credit",
        "total_amount": 60000,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiMjA1MCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories": [
          {
            "parent_id": "Spend_Category_ID",
            "id": "Legal_and_Auditing_Fees"
          },
          {
            "parent_id": "Cost_Center_Reference_ID",
            "id": "50000_Office_of_CFO"
          }
        ]
      }
    ],
    "created_at": "2021-08-08T17:28:20Z",
    "updated_at": "2021-08-08T17:37:04Z"
  }
}

Get All Journal Entries

GET /accounting/journal-entries returns a list of journal entries.

Example:

GET /accounting/journal-entries

Response Structure:

{
  "status_code": 200,
  "data": [
    {
      "id": "...",
      "number": "10783",
      "status": "posted",
      "posted_at": "2025-01-15T00:00:00Z",
      "total_amount": 60000,
      "currency": "USD",
      "company_id": "Global_Modern_Services_Inc_USA",
      "memo": "Q2 Audit Accrual",
      "line_items": [...],
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "meta": {
    "items_on_page": 1,
    "cursors": {
      "previous": null,
      "current": "page=1",
      "next": null
    }
  }
}

III. Expenses

Problem Overview

Workday doesn't have a dedicated "Expense" API resource. Instead, expenses are recorded as a specific type of Accounting Journal where:

  • Debit lines represent expense accounts (where money was spent)
  • Credit line represents the payment account (cash, bank, or credit card)
  • Journal Source is typically set to identify expense-related entries

Apideck abstracts this by providing an Expenses resource that:

  • Accepts simplified expense line items (just amounts and accounts)
  • Automatically generates the offsetting payment/credit line
  • Uses Workday's Submit_Accounting_Journal under the hood

Initial Setup

No additional expense-specific configuration is required. Apideck's expense operations use the same Workday journal mechanisms as journal entries.

Adding Expenses (Create)

When you add an expense via Apideck, you specify the expense lines and payment source. Apideck automatically:

  1. Creates expense lines as journal entry debits
  2. Generates balancing credit line from the account field
  3. Sets appropriate journal source and tracking

Expense Request Structure

{
  "transaction_date": "2025-01-15",
  "account": {
    "id": "eyJBY2NvdW50X0lkIjoiMTAwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
  },
  "tracking_categories" : [
    {
      "id": "820000_Sale_Department",
      "parent_id": "Cost_Center_Reference_ID"
    }
  ],
  "currency": "USD",
  "company_id": "Global_Modern_Services_Inc_USA",
  "memo": "Travel expenses - Client visit",
  "number": "EXP-2025-001",
  "status": "draft",
  "line_items": [
    {
      "total_amount": 450.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjEwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      },
      "tracking_categories": [
        {
          "parent_id": "Cost_Center_Reference_ID",
          "id": "40000_Sales_Department"
        }
      ]
    },
    {
      "total_amount": 250.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjExMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      },
      "tracking_categories": [
        {
          "parent_id": "Cost_Center_Reference_ID",
          "id": "40000_Sales_Department"
        }
      ]
    }
  ]
}

How Multiple Lines Are Created

Your expense input:

  • 2 expense line items totaling $700.00 (debits)
  • 1 payment account (credit)

Apideck generates journal entry:

Line 1: Debit  $450.00 - Travel Transportation (6100)
Line 2: Debit  $250.00 - Travel Lodging (6110)
Line 3: Credit $700.00 - Corporate Credit Card (1000)  ← Auto-generated

Result: Balanced journal entry with 3 lines that represents the complete expense transaction.

Request to Apideck

POST /accounting/expenses
Content-Type: application/json
x-apideck-app-id: your-app-id
x-apideck-service-id: workday

{
  "transaction_date": "2025-01-15",
  "account": {
    "id": "eyJBY2NvdW50X0lkIjoiMTAwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
  },
  "currency": "USD",
  "company_id": "Global_Modern_Services_Inc_USA",
  "memo": "Travel expenses",
  "status": "draft",
  "line_items": [
    {
      "total_amount": 450.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjEwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    },
    {
      "total_amount": 250.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjExMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    }
  ]
}

What Happens Behind the Scenes

Workday Processing:

  • Validates the journal entry structure
  • Checks business rules and permissions
  • Assigns WID and journal number
  • Sets initial status based on submission flag

Response Structure:

{
  "status_code": 200,
  "data": {
    "id": "a10dee2ca7258147170cb396fe154022",
    "transaction_date": "2025-01-15T00:00:00Z",
    "total_amount": 700.00,
    "type": "expense",
    "status": "draft",
    "currency": "USD",
    "company_id": "Global_Modern_Services_Inc_USA",
    "memo": "Travel expenses",
    "account": {
      "id": "eyJBY2NvdW50X0lkIjoiMTAwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
    },
    "tracking_categories" : [
      {
        "parent_id": "Cost_Center_Reference_ID",
        "id": "40000_Sales_Department"
      }
    ],
    "line_items": [
      {
        "total_amount": 450.00,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiNjEwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories" : [
          {
            "parent_id": "Cost_Center_Reference_ID",
            "id": "40000_Sales_Department"
          }
        ],
      },
      {
        "total_amount": 250.00,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiNjExMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories" : [
          {
            "parent_id": "Cost_Center_Reference_ID",
            "id": "40000_Sales_Department"
          }
        ]
      }
    ],
    "created_at": "2025-01-15T14:23:10Z",
    "updated_at": "2025-01-15T14:23:10Z"
  }
}

Key Aspects of Expense Creation

Automatic Balancing

You provide:

{
  "account": { "id": "credit-card-account" },  // Payment source
  "line_items": [
    { "total_amount": 450.00, "ledger_account": {...} },  // Expense 1
    { "total_amount": 250.00, "ledger_account": {...} }   // Expense 2
  ]
}

Apideck generates:

Debit:  $450.00 - Travel Transportation (Expense line 1)
Debit:  $250.00 - Travel Lodging       (Expense line 2)
Credit: $700.00 - Corporate Credit Card (Auto-generated from account)
-----------------------------------------------------
Total:  $700.00 = $700.00 ✓ Balanced

Worktags (Tracking Categories)

Workday's Worktags are flexible dimensions for tracking expenses by cost center, project, region, etc.

Tracking Categories Structure:

{
  "tracking_categories": [
    {
      "id": "40000_Sales_Department",        
      "parent_id": "Cost_Center_Reference_ID"          
    },
    {
      "id": "Travel_Entertainment",
      "parent_id": "Spend_Category_ID"
    },
    {
      "id": "PRJ-2025-Q1-Expansion",
      "parent_id": "Project_ID"
    }
  ]
}

Common Worktag Types:

  • Cost_Center_Reference_ID: Cost center allocation (required when creating a journal-entry)
  • Spend_Category_ID: Expense category classification
  • Project_ID: Project tracking
  • Region_ID: Geographic tracking

Applied to Line Items: Each expense line can have its own set of worktags, allowing detailed expense allocation:

{
  "line_items": [
    {
      "description": "Airfare - East Coast",
      "total_amount": 450.00,
      "ledger_account": {...},
      "tracking_categories": [
        { "parent_id": "Cost_Center_Reference_ID", "id": "40000_Sales" },
        { "parent_id": "Region_ID", "id": "US_East" }
      ]
    },
    {
      "description": "Hotel - West Coast",
      "total_amount": 250.00,
      "ledger_account": {...},
      "tracking_categories": [
        { "parent_id": "Cost_Center_Reference_ID", "id": "40000_Sales" },
        { "parent_id": "Region_ID", "id": "US_West" }
      ]
    }
  ]
}

Status Control

Expenses support the same status workflow as journal entries:

  • draft: Save expense without submitting for approval
  • posted: Submit and attempt to post to ledger

Updating an Expense

Like journal entries, expenses can only be updated while in draft status.

Update Request:

PATCH /accounting/expenses/{id}
Content-Type: application/json

{
  "memo": "Updated travel expenses",
  "line_items": [
    {
      "total_amount": 475.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjEwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      },
      "tracking_categories": [
        { "parent_id": "Cost_Center_Reference_ID", "id": "40000_Sales" },
        { "parent_id": "Region_ID", "id": "US_East" }
      ]
    },
    {
      "total_amount": 275.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjExMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      },
      "tracking_categories": [
        { "parent_id": "Cost_Center_Reference_ID", "id": "40000_Sales" },
        { "parent_id": "Region_ID", "id": "US_East" }
      ]
    }
  ]
}

Behind the Scenes:

  1. Apideck fetches existing expense journal from Workday
  2. Validates expense is in draft status
  3. Merges updates with existing data
  4. Recalculates payment line credit amount ($750.00 total)
  5. Submits updated journal to Workday with new line structure

Important:

  • Update replaces ALL expense lines
  • Payment account credit line is automatically recalculated

Posting (Approving) an Expense

Posting an expense follows the same workflow as journal entries. Update the status to trigger submission:

Option 1: Create Posted Expense

POST /accounting/expenses
{
  "status": "posted",  // Submit immediately
  "transaction_date": "2025-01-15",
  "account": { "id": "..." },
  "line_items": [...]
}

Option 2: Post Draft Expense

PATCH /accounting/expenses/{id}
{
  "status": "posted"  // Submit existing draft
}

Checking Status:

GET /accounting/expenses/{id}

{
  "id": "a10dee2ca7258147170cb396fe154022",
  "status": "posted",  // Successfully posted
  "posted_at": "2025-01-15T00:00:00Z",
  "total_amount": 700.00,
  ...
}

Retrieving Expenses (Get One / Get All)

Get One Expense

GET /accounting/expenses/{id} retrieves a specific expense by its WID.

Example Response:

{
  "status_code": 200,
  "data": {
    "id": "a10dee2ca7258147170cb396fe154022",
    "number": "10783",
    "transaction_date": "2025-01-15T00:00:00Z",
    "total_amount": 700.00,
    "type": "expense",
    "status": "posted",
    "currency": "USD",
    "company_id": "Global_Modern_Services_Inc_USA",
    "memo": "Travel expenses",
    "account": {
      "id": "eyJBY2NvdW50X0lkIjoiMTAwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
    },
    "tracking_categories": [
      {
        "parent_id": "Cost_Center_Reference_ID",
        "id": "40000_Sales_Department"
      }
    ],
    "line_items": [
      {
        "total_amount": 450.00,
        "unit_price": 450.00,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiNjEwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories": [...]
      },
      {
        "total_amount": 250.00,
        "unit_price": 250.00,
        "ledger_account": {
          "id": "eyJBY2NvdW50X0lkIjoiNjExMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
        },
        "tracking_categories": [...]
      }
    ],
    "created_at": "2025-01-15T14:23:10Z",
    "updated_at": "2025-01-15T14:23:10Z"
  }
}

Get All Expenses

GET /accounting/expenses returns expenses.

Example Request:

GET /accounting/expenses

Response:

{
  "status_code": 200,
  "data": [
    {
      "id": "a10dee2ca7258147170cb396fe154022",
      "number": "10783",
      "transaction_date": "2025-01-15T00:00:00Z",
      "total_amount": 700.00,
      "type": "expense",
      "status": "posted",
      "currency": "USD",
      "account": {
        "id": "...",
      },
      "line_items": [...],
      "created_at": "2025-01-15T14:23:10Z",
      "updated_at": "2025-01-15T14:23:10Z"
    }
  ],
  "meta": {
    "items_on_page": 1,
    "cursors": {
      "previous": null,
      "current": "page=1",
      "next": null
    }
  }
}

IV. Workday-Specific Considerations

Account Sets and Multi-Dimensional Accounting

Understanding Account Sets

Account Reference Structure:

<wd:Ledger_Account_Reference>
  <wd:ID wd:type="Ledger_Account_ID" 
         wd:parent_type="Account_Set_ID" 
         wd:parent_id="Corporate">6400</wd:ID>
</wd:Ledger_Account_Reference>

How Apideck Handles Account Sets

Encoding: When you use Apideck's Ledger Accounts API, you receive encoded account IDs:

GET /accounting/ledger-accounts/eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0=

# Decoded structure:
{
  "Account_Id": "6400",
  "Account_Set_Id": "Corporate"
}

In Expense/Journal Requests:

{
  "line_items": [
    {
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="
      }
    }
  ]
}

Apideck's Transformation:

  1. Decodes base64 ID
  2. Extracts Account_Id and Account_Set_Id
  3. Constructs proper Workday XML structure
  4. Sends to Workday with correct parent references

Working with Different Account Sets

If you need to record transactions in multiple accounting frameworks:

{
  "line_items": [
    {
      "description": "Legal Fees",
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiQ29ycG9yYXRlIn0="  // Corporate framework
      }
    },
    {
      "description": "Legal Fees",
      "total_amount": 5000.00,
      "ledger_account": {
        "id": "eyJBY2NvdW50X0lkIjoiNjQwMCIsIkFjY291bnRfU2V0X0lkIjoiR0FBUCJ9"  // GAAP framework
      }
    }
  ]
}

Worktags: Workday's Flexible Tracking

What Are Worktags?

Worktags are Workday's answer to traditional accounting dimensions/segments. Instead of fixed dimensions, Workday allows flexible tagging with type-specific tags:

Standard Worktag Types:

  • Cost Centers: Organizational units (departments, divisions)
  • Spend Categories: Expense classification (travel, supplies, professional fees)
  • Projects: Project/grant tracking
  • Regions: Geographic allocation

Worktag Structure in Apideck

Request Format (tracking_categories):

{
  "tracking_categories": [
    {
      "parent_id": "Cost_Center_Reference_ID",        
      "id": "50000_Office_of_CFO"            
    },
    {
      "parent_id": "Spend_Category_ID",
      "id": "Legal_and_Auditing_Fees"
    },
    {
      "parent_id": "Project_ID",
      "id": "PRJ-2025-Digital-Transformation"
    }
  ]
}

Workday XML Structure:

<wd:Worktags_Reference>
  <wd:ID wd:type="Cost_Center_Reference_ID">50000_Office_of_CFO</wd:ID>
</wd:Worktags_Reference>
<wd:Worktags_Reference>
  <wd:ID wd:type="Spend_Category_ID">Legal_and_Auditing_Fees</wd:ID>
</wd:Worktags_Reference>

Worktag Best Practices

1. Validate Worktag Compatibility:

  • Not all worktag combinations are valid in Workday
  • Some worktags are required based on ledger account configuration
  • Workday validates worktags at submission time

2. Use Reference IDs: Worktag type IDs commonly end in _Reference_ID or _ID:

  • Cost_Center_Reference_ID
  • Spend_Category_ID
  • Project_ID
  • Region_Reference_ID

SOAP/XML Abstraction

Apideck Handles SOAP Complexity

Working directly with Workday SOAP APIs requires:

  • XML envelope construction
  • WSSE security headers
  • Namespace management
  • Complex nested structures

Direct SOAP Request (340+ lines):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:wd="urn:com.workday/bsvc">
  <soapenv:Header>
    <wsse:Security>
      <wsse:UsernameToken>
        <wsse:Username>integrationuser@tenant</wsse:Username>
        <wsse:Password>password</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body>
    <wd:Submit_Accounting_Journal_Request wd:Add_Only="true">
      <wd:Business_Process_Parameters>
        <wd:Auto_Complete>true</wd:Auto_Complete>
      </wd:Business_Process_Parameters>
      <wd:Accounting_Journal_Data>
        <wd:Company_Reference>
          <wd:ID wd:type="Organization_Reference_ID">Global_Modern_Services_Inc_USA</wd:ID>
        </wd:Company_Reference>
        <wd:Currency_Reference>
          <wd:ID wd:type="Currency_ID">USD</wd:ID>
        </wd:Currency_Reference>
        <wd:Accounting_Date>2025-01-15</wd:Accounting_Date>
        <wd:Journal_Entry_Line_Replacement_Data>
          <!-- Complex line structure for each debit/credit -->
        </wd:Journal_Entry_Line_Replacement_Data>
      </wd:Accounting_Journal_Data>
    </wd:Submit_Accounting_Journal_Request>
  </soapenv:Body>
</soapenv:Envelope>

Apideck Request (Simple JSON):

POST /accounting/expenses
{
  "transaction_date": "2025-01-15",
  "account": { "id": "..." },
  "currency": "USD",
  "company_id": "Global_Modern_Services_Inc_USA",
  "line_items": [
    { "description": "Airfare", "total_amount": 450.00, "ledger_account": {...} },
    { "description": "Hotel", "total_amount": 250.00, "ledger_account": {...} }
  ]
}

Apideck handles:

  • ✅ SOAP envelope construction
  • ✅ WSSE authentication
  • ✅ XML namespace management
  • ✅ Account Set encoding/decoding
  • ✅ Worktag structure conversion
  • ✅ Line item XML formatting
  • ✅ Status code translation
  • ✅ Error handling and rollback

V. Comparison: Expenses vs Journal Entries in Workday

When to Use Each Resource

Use Expenses When:

  • ✅ Recording "already paid" purchases
  • ✅ Simple expense transactions (purchase + payment)
  • ✅ Want automatic payment line generation
  • ✅ Line items are all expenses with one payment source
  • ✅ Prefer simplified API with less accounting detail

Use Journal Entries When:

  • ✅ Need explicit control over all debits and credits
  • ✅ Recording accounting adjustments or accruals
  • ✅ Complex multi-line transactions
  • ✅ Need full flexibility in line structure

Implementation Differences

Expenses Implementation

// Apideck receives:
{
  "account": { "id": "credit-card" },
  "line_items": [
    { "total_amount": 450, ledger_account: {...} },
    { "total_amount": 250, ledger_account: {...} }
  ]
}

// Hook generates journal structure:
{
  "Journal_Entry_Line_Replacement_Data": [
    { "Debit_Amount": "450", "Ledger_Account_Reference": {...} },
    { "Debit_Amount": "250", "Ledger_Account_Reference": {...} },
    { "Credit_Amount": "700", "Ledger_Account_Reference": {credit-card} } 
  ]
}

Journal Entries Implementation

// Apideck receives:
{
  "line_items": [
    { "type": "debit", "total_amount": 5000, "ledger_account": {...} },
    { "type": "credit", "total_amount": 5000, "ledger_account": {...} }
  ]
}

// Mapping directly converts:
{
  "Journal_Entry_Line_Replacement_Data": [
    { "Debit_Amount": "5000", "Ledger_Account_Reference": {...} },
    { "Credit_Amount": "5000", "Ledger_Account_Reference": {...} }
  ]
}

Conclusion

Using Apideck's unified API for Workday Financial Management dramatically simplifies working with resources that Workday implements through complex SOAP operations. This guide covered three interconnected resources that form the foundation of financial data management:

Three Core Resources

1. Ledger Accounts:

  • Multi-dimensional chart of accounts organized by Account Sets (Corporate, GAAP, IFRS, Tax)
  • Base64-encoded IDs that combine Account_Id + Account_Set_Id
  • Hierarchical account structures with parent-child relationships
  • REST endpoints for retrieval

2. Journal Entries:

  • Full control over debit/credit transactions for any accounting operation
  • Support for draft, and posted workflows
  • Manual balancing requirement with explicit line types
  • Suitable for adjustments, accruals, reclassifications, and complex transactions

3. Expenses:

  • Streamlined interface for recording already-paid purchases
  • Automatic payment line generation from the account field
  • Same approval workflow as journal entries
  • Optimized for simple purchase transactions

What Apideck Handles Automatically

All three resources benefit from Apideck's abstraction layer:

  • SOAP/XML Complexity: No need to construct XML envelopes or manage namespaces
  • Account Set Encoding: Transparent encoding/decoding of multi-part account references
  • Worktag Transformation: Simple JSON tracking_categories → complex Workday Worktag XML
  • Error Handling: Consistent error responses with actionable validation messages
  • Atomic Operations: Transaction safety with proper rollback on failures

Workday's Unique Features

Account Sets:

  • Support multiple accounting frameworks simultaneously
  • Same account number can exist in Corporate, GAAP, IFRS, and Tax Account Sets
  • Each framework maintains independent balances and configurations

Worktags:

  • Flexible tagging system beyond traditional dimensions
  • Support for cost centers, projects, regions, spend categories, and custom tags
  • Applied at line-item and header level for detailed tracking

Immutability:

  • Posted entries become part of permanent ledger
  • No risk of accidental modification after posting

Integration Benefits

By leveraging Apideck's Workday connector, developers can:

  1. Work with familiar REST JSON APIs instead of learning SOAP/XML
  2. Use encoded account IDs without understanding Workday's multi-ID system
  3. Apply worktags using simple key-value pairs
  4. Create transactions with automatic SOAP envelope construction
  5. Track status through unified workflow states
  6. Handle errors with consistent validation messages

This allows you to focus on your application logic while ensuring accurate, compliant financial data in Workday's sophisticated financial management system. Whether you're building expense reporting, financial consolidation, or accounting automation, Apideck provides the abstraction layer that makes Workday integration straightforward and maintainable.


Apideck Documentation: