Monument

Invoices

Invoice generation, approval, lifecycle, and line item operations.

externalpermissionstable17 procedures
queryinvoices.listInferred output

List invoices for the organization with optional filters.

Input
{
  status?: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | undefined;
  rootTaskId?: string | undefined;
  limit?: number | undefined;
  offset?: number | undefined;
  contactId?: string | undefined;
  projectId?: string | undefined;
  issuedAfter?: string | undefined;
  issuedBefore?: string | undefined;
  dueBefore?: string | undefined;
  includeVoid?: boolean | undefined;
}
Output
{
  data: Array<{
    contactName: string | null;
    id: string;
    status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
    organizationId: string;
    rootTaskId: string | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
    notes: string | null;
    billingAddress: string | null;
    contactId: string | null;
    currency: string | null;
    lastSyncedAt: Date | null;
    issuedDate: string | null;
    subtotal: string | null;
    tax: string | null;
    total: string | null;
    accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
    accountingSystemId: "xero" | "quickbooks" | "myob" | null;
    lastSyncError: string | null;
    syncedVersionHash: string | null;
    pdfUrl: string | null;
    pdfKey: string | null;
    pdfGeneratedAt: Date | null;
    attentionContactId: string | null;
    milestoneId: string | null;
    invoiceNumber: string;
    dueDate: string | null;
    paidDate: string | null;
    amountPaid: string | null;
    amountDue: string | null;
    paymentTerms: string | null;
    cachedProjectName: string | null;
    cachedProjectCode: string | null;
    accountingSystemInvoiceId: string | null;
    projectId: string | null;
  }>;
  total: number;
  limit: number;
  offset: number;
}
queryinvoices.getByIdInferred output

Get a single invoice by ID with optional lines.

Input
{
  id: string;
  includeLines?: boolean | undefined;
}
Output
({
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
} & {
  projectId: string | null;
}) | {
  contact: {
    id: string;
    organizationId: string;
    parentContactId: string | null;
    contactType: "company" | "individual";
    relationshipType: "client" | "consultant" | "supplier" | "other";
    name: string;
    email: string | null;
    phone: string | null;
    jobTitle: string | null;
    billingEmail: string | null;
    billingAddress: string | null;
    paymentTermsDays: number | null;
    isBillable: boolean | null;
    isActive: boolean | null;
    emailBounced: boolean | null;
    emailBouncedAt: Date | null;
    website: string | null;
    taxNumber: string | null;
    notes: string | null;
    tags: Array<string> | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
  } | null;
  attentionContact: {
    id: string;
    organizationId: string;
    parentContactId: string | null;
    contactType: "company" | "individual";
    relationshipType: "client" | "consultant" | "supplier" | "other";
    name: string;
    email: string | null;
    phone: string | null;
    jobTitle: string | null;
    billingEmail: string | null;
    billingAddress: string | null;
    paymentTermsDays: number | null;
    isBillable: boolean | null;
    isActive: boolean | null;
    emailBounced: boolean | null;
    emailBouncedAt: Date | null;
    website: string | null;
    taxNumber: string | null;
    notes: string | null;
    tags: Array<string> | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
  } | null;
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
  projectId: string | null;
} | {
  contact: {
    id: string;
    organizationId: string;
    parentContactId: string | null;
    contactType: "company" | "individual";
    relationshipType: "client" | "consultant" | "supplier" | "other";
    name: string;
    email: string | null;
    phone: string | null;
    jobTitle: string | null;
    billingEmail: string | null;
    billingAddress: string | null;
    paymentTermsDays: number | null;
    isBillable: boolean | null;
    isActive: boolean | null;
    emailBounced: boolean | null;
    emailBouncedAt: Date | null;
    website: string | null;
    taxNumber: string | null;
    notes: string | null;
    tags: Array<string> | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
  } | null;
  attentionContact: {
    id: string;
    organizationId: string;
    parentContactId: string | null;
    contactType: "company" | "individual";
    relationshipType: "client" | "consultant" | "supplier" | "other";
    name: string;
    email: string | null;
    phone: string | null;
    jobTitle: string | null;
    billingEmail: string | null;
    billingAddress: string | null;
    paymentTermsDays: number | null;
    isBillable: boolean | null;
    isActive: boolean | null;
    emailBounced: boolean | null;
    emailBouncedAt: Date | null;
    website: string | null;
    taxNumber: string | null;
    notes: string | null;
    tags: Array<string> | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
  } | null;
  lines: Array<{
    id: string;
    type: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group";
    organizationId: string;
    taskId: string | null;
    createdAt: Date;
    updatedAt: Date | null;
    deletedAt: Date | null;
    description: string;
    hours: string | null;
    amount: string;
    invoiceId: string;
    quantity: string | null;
    parentLineId: string | null;
    sortOrder: number;
    unitValue: string | null;
    revenueItemIds: Array<string> | null;
    progressPercentage: string | null;
    absorbedTimeEntryIds: Array<string> | null;
    absorbedExpenseIds: Array<string> | null;
    timeFilters: TimeFilters | null;
    timeGrouping: TimeGrouping | null;
    timeSort: LineSort | null;
    timeRateOverrides: Array<TimeRateOverride> | null;
    timeRowOverrides: Array<TimeRowOverride> | null;
    timeDescriptionTemplate: string | null;
    excludedTimeEntryIds: Array<string> | null;
    expenseFilters: ExpenseFilters | null;
    expenseGrouping: ExpenseGrouping | null;
    expenseSort: LineSort | null;
    expenseDescriptionTemplate: string | null;
    excludedExpenseIds: Array<string> | null;
    expenseDescriptionOverrides: Record<string, string> | null;
    previousLineIds: Array<string> | null;
    isAutoGenerated: boolean;
    autoGroupKey: string | null;
  }>;
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
  projectId: string | null;
} | null
mutationinvoices.createInferred output

Create a new invoice.

Input
{
  status?: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | undefined;
  rootTaskId?: string | undefined;
  notes?: string | undefined;
  billingAddress?: string | undefined;
  contactId?: string | undefined;
  currency?: string | undefined;
  projectId?: string | undefined;
  issuedDate?: string | undefined;
  subtotal?: number | undefined;
  tax?: number | undefined;
  total?: number | undefined;
  attentionContactId?: string | undefined;
  milestoneId?: string | undefined;
  invoiceNumber?: string | undefined;
  dueDate?: string | undefined;
  paymentTerms?: string | undefined;
}
Output
{
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
} & {
  projectId: string | null;
}
mutationinvoices.updateInferred output

Update an invoice.

Input
{
  id: string;
  status?: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | undefined;
  rootTaskId?: string | null | undefined;
  notes?: string | null | undefined;
  billingAddress?: string | null | undefined;
  contactId?: string | undefined;
  currency?: string | undefined;
  projectId?: string | null | undefined;
  issuedDate?: string | null | undefined;
  subtotal?: number | undefined;
  tax?: number | undefined;
  total?: number | undefined;
  attentionContactId?: string | null | undefined;
  milestoneId?: string | null | undefined;
  invoiceNumber?: string | undefined;
  dueDate?: string | null | undefined;
  paidDate?: string | null | undefined;
  amountPaid?: number | undefined;
  amountDue?: number | undefined;
  paymentTerms?: string | null | undefined;
}
Output
({
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
} & {
  projectId: string | null;
}) | null
mutationinvoices.deleteInferred output

Soft delete an invoice.

Input
{
  id: string;
}
Output
{
  success: boolean;
  error: string;
} | {
  success: boolean;
  error?: undefined;
}
mutationinvoices.addLineInferred output

Add a line to an invoice.

Input
{
  type: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group";
  invoiceId: string;
  taskId?: string | null | undefined;
  description?: string | undefined;
  quantity?: number | null | undefined;
  parentLineId?: string | null | undefined;
  sortOrder?: number | undefined;
  unitValue?: number | null | undefined;
  revenueItemIds?: Array<string> | null | undefined;
  progressPercentage?: number | null | undefined;
  absorbedTimeEntryIds?: Array<string> | null | undefined;
  absorbedExpenseIds?: Array<string> | null | undefined;
  timeFilters?: {
    dateFrom: string | null;
    dateTo: string | null;
    poolIds: Array<string> | null;
    resourceIds: Array<string> | null;
    billableOnly: boolean;
  } | null | undefined;
  timeGrouping?: "per_pool" | "per_resource" | "per_entry" | "lumped" | null | undefined;
  timeSort?: "date_asc" | "date_desc" | "amount_desc" | "label_asc" | null | undefined;
  timeRateOverrides?: Array<{
    scope: "resource" | "pool" | "entry";
    rate: number;
    key: string;
  }> | null | undefined;
  timeRowOverrides?: Array<{
    scope: "resource" | "pool" | "entry";
    key: string;
    description?: string | null | undefined;
    hours?: number | null | undefined;
  }> | null | undefined;
  timeDescriptionTemplate?: string | null | undefined;
  excludedTimeEntryIds?: Array<string> | null | undefined;
  expenseFilters?: {
    dateFrom: string | null;
    dateTo: string | null;
    supplierIds: Array<string> | null;
    categoryIds: Array<string> | null;
    contactIds: Array<string> | null;
  } | null | undefined;
  expenseGrouping?: "lumped" | "per_expense" | null | undefined;
  expenseSort?: "date_asc" | "date_desc" | "amount_desc" | "label_asc" | null | undefined;
  expenseDescriptionTemplate?: string | null | undefined;
  excludedExpenseIds?: Array<string> | null | undefined;
  expenseDescriptionOverrides?: Record<string, string> | null | undefined;
  previousLineIds?: Array<string> | null | undefined;
}
Output
{
  id: string;
  type: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group";
  organizationId: string;
  taskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  description: string;
  hours: string | null;
  amount: string;
  invoiceId: string;
  quantity: string | null;
  parentLineId: string | null;
  sortOrder: number;
  unitValue: string | null;
  revenueItemIds: Array<string> | null;
  progressPercentage: string | null;
  absorbedTimeEntryIds: Array<string> | null;
  absorbedExpenseIds: Array<string> | null;
  timeFilters: TimeFilters | null;
  timeGrouping: TimeGrouping | null;
  timeSort: LineSort | null;
  timeRateOverrides: Array<TimeRateOverride> | null;
  timeRowOverrides: Array<TimeRowOverride> | null;
  timeDescriptionTemplate: string | null;
  excludedTimeEntryIds: Array<string> | null;
  expenseFilters: ExpenseFilters | null;
  expenseGrouping: ExpenseGrouping | null;
  expenseSort: LineSort | null;
  expenseDescriptionTemplate: string | null;
  excludedExpenseIds: Array<string> | null;
  expenseDescriptionOverrides: Record<string, string> | null;
  previousLineIds: Array<string> | null;
  isAutoGenerated: boolean;
  autoGroupKey: string | null;
}
mutationinvoices.updateLineInferred output

Update an invoice line.

Input
{
  id: string;
  type?: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group" | undefined;
  taskId?: string | null | undefined;
  description?: string | undefined;
  quantity?: number | null | undefined;
  parentLineId?: string | null | undefined;
  sortOrder?: number | undefined;
  unitValue?: number | null | undefined;
  revenueItemIds?: Array<string> | null | undefined;
  progressPercentage?: number | null | undefined;
  absorbedTimeEntryIds?: Array<string> | null | undefined;
  absorbedExpenseIds?: Array<string> | null | undefined;
  timeFilters?: {
    dateFrom: string | null;
    dateTo: string | null;
    poolIds: Array<string> | null;
    resourceIds: Array<string> | null;
    billableOnly: boolean;
  } | null | undefined;
  timeGrouping?: "per_pool" | "per_resource" | "per_entry" | "lumped" | null | undefined;
  timeSort?: "date_asc" | "date_desc" | "amount_desc" | "label_asc" | null | undefined;
  timeRateOverrides?: Array<{
    scope: "resource" | "pool" | "entry";
    rate: number;
    key: string;
  }> | null | undefined;
  timeRowOverrides?: Array<{
    scope: "resource" | "pool" | "entry";
    key: string;
    description?: string | null | undefined;
    hours?: number | null | undefined;
  }> | null | undefined;
  timeDescriptionTemplate?: string | null | undefined;
  excludedTimeEntryIds?: Array<string> | null | undefined;
  expenseFilters?: {
    dateFrom: string | null;
    dateTo: string | null;
    supplierIds: Array<string> | null;
    categoryIds: Array<string> | null;
    contactIds: Array<string> | null;
  } | null | undefined;
  expenseGrouping?: "lumped" | "per_expense" | null | undefined;
  expenseSort?: "date_asc" | "date_desc" | "amount_desc" | "label_asc" | null | undefined;
  expenseDescriptionTemplate?: string | null | undefined;
  excludedExpenseIds?: Array<string> | null | undefined;
  expenseDescriptionOverrides?: Record<string, string> | null | undefined;
  previousLineIds?: Array<string> | null | undefined;
}
Output
{
  id: string;
  type: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group";
  organizationId: string;
  taskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  description: string;
  hours: string | null;
  amount: string;
  invoiceId: string;
  quantity: string | null;
  parentLineId: string | null;
  sortOrder: number;
  unitValue: string | null;
  revenueItemIds: Array<string> | null;
  progressPercentage: string | null;
  absorbedTimeEntryIds: Array<string> | null;
  absorbedExpenseIds: Array<string> | null;
  timeFilters: TimeFilters | null;
  timeGrouping: TimeGrouping | null;
  timeSort: LineSort | null;
  timeRateOverrides: Array<TimeRateOverride> | null;
  timeRowOverrides: Array<TimeRowOverride> | null;
  timeDescriptionTemplate: string | null;
  excludedTimeEntryIds: Array<string> | null;
  expenseFilters: ExpenseFilters | null;
  expenseGrouping: ExpenseGrouping | null;
  expenseSort: LineSort | null;
  expenseDescriptionTemplate: string | null;
  excludedExpenseIds: Array<string> | null;
  expenseDescriptionOverrides: Record<string, string> | null;
  previousLineIds: Array<string> | null;
  isAutoGenerated: boolean;
  autoGroupKey: string | null;
} | null
mutationinvoices.removeLineInferred output

Remove a line from an invoice.

Input
{
  id: string;
}
Output
{
  success: boolean;
  error: string;
} | {
  success: boolean;
  error?: undefined;
}
mutationinvoices.recalculateTotalsInferred output

Recalculate invoice totals from lines.

Input
{
  id: string;
}
Output
{
  id: string;
  status: "draft" | "paid" | "partial" | "sent" | "viewed" | "overdue" | "void" | null;
  organizationId: string;
  rootTaskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  notes: string | null;
  billingAddress: string | null;
  contactId: string | null;
  currency: string | null;
  lastSyncedAt: Date | null;
  issuedDate: string | null;
  subtotal: string | null;
  tax: string | null;
  total: string | null;
  accountingSyncStatus: "not_synced" | "synced" | "modified" | "sync_failed" | "syncing" | null;
  accountingSystemId: "xero" | "quickbooks" | "myob" | null;
  lastSyncError: string | null;
  syncedVersionHash: string | null;
  pdfUrl: string | null;
  pdfKey: string | null;
  pdfGeneratedAt: Date | null;
  attentionContactId: string | null;
  milestoneId: string | null;
  invoiceNumber: string;
  dueDate: string | null;
  paidDate: string | null;
  amountPaid: string | null;
  amountDue: string | null;
  paymentTerms: string | null;
  cachedProjectName: string | null;
  cachedProjectCode: string | null;
  accountingSystemInvoiceId: string | null;
} | {
  success: boolean;
  error: string;
}
mutationinvoices.generatePdfInferred output

Generate PDF for an invoice. Triggers async PDF generation via Inngest.

Input
{
  invoiceId: string;
  regenerate?: boolean | undefined;
}
Output
{
  success: boolean;
  error: string;
  message?: undefined;
  invoiceId?: undefined;
} | {
  success: boolean;
  message: string;
  invoiceId: string;
  error?: undefined;
}
queryinvoices.getPdfUrlInferred output

Get PDF URL for an invoice (for polling completion status).

Input
{
  invoiceId: string;
}
Output
{
  ready: boolean;
  error: string;
  url?: undefined;
  generatedAt?: undefined;
} | {
  ready: boolean;
  url: string | null;
  generatedAt: Date | null;
  error?: undefined;
}
queryinvoices.getPreviousLinesForTaskInferred output

Get previous invoice lines for a task (for "less previously billed" feature). Returns lines from all non-void invoices for this task.

Input
{
  taskId: string;
  includeChildTasks?: boolean | undefined;
  excludeInvoiceId?: string | undefined;
}
Output
Array<{
  id: string;
  type: "fixed" | "from_expenses" | "notes" | "progress" | "from_time" | "previously_billed" | "group";
  organizationId: string;
  taskId: string | null;
  createdAt: Date;
  updatedAt: Date | null;
  deletedAt: Date | null;
  description: string;
  hours: string | null;
  amount: string;
  invoiceId: string;
  quantity: string | null;
  parentLineId: string | null;
  sortOrder: number;
  unitValue: string | null;
  revenueItemIds: Array<string> | null;
  progressPercentage: string | null;
  absorbedTimeEntryIds: Array<string> | null;
  absorbedExpenseIds: Array<string> | null;
  timeFilters: TimeFilters | null;
  timeGrouping: TimeGrouping | null;
  timeSort: LineSort | null;
  timeRateOverrides: Array<TimeRateOverride> | null;
  timeRowOverrides: Array<TimeRowOverride> | null;
  timeDescriptionTemplate: string | null;
  excludedTimeEntryIds: Array<string> | null;
  expenseFilters: ExpenseFilters | null;
  expenseGrouping: ExpenseGrouping | null;
  expenseSort: LineSort | null;
  expenseDescriptionTemplate: string | null;
  excludedExpenseIds: Array<string> | null;
  expenseDescriptionOverrides: Record<string, string> | null;
  previousLineIds: Array<string> | null;
  isAutoGenerated: boolean;
  autoGroupKey: string | null;
} & {
  invoiceNumber: string | null;
  invoiceStatus: string | null;
  issuedDate: string | null;
}>
queryinvoices.getTaskFeeForProgressInferred output

Get task fee amount for progress calculation. Returns total task fee and previously billed amount.

Input
{
  taskId: string;
}
Output
{
  taskFeeAmount: number;
  previouslyBilledAmount: number;
  availableAmount: number;
}
queryinvoices.timeEntryCandidatesInferred output

Get time-entry candidates for a From-Time invoice line. Returns entries matching the line's filters with resolved rates and an isExcluded flag (excluded entries are still returned so the panel can grey them out and offer re-inclusion).

Input
{
  invoiceId: string;
  taskId?: string | undefined;
  lineId?: string | undefined;
}
Output
Array<TimeEntryCandidate>
queryinvoices.expenseCandidatesInferred output

Get expense candidates for a From-Expenses invoice line.

Input
{
  invoiceId: string;
  taskId?: string | undefined;
  lineId?: string | undefined;
}
Output
Array<ExpenseCandidate>
queryinvoices.previousBillingCandidatesInferred output

Get prior sent invoice lines for a task subtree.

Input
{
  taskId: string;
  invoiceId: string;
}
Output
Array<PreviousBillingCandidate>
mutationinvoices.sendInvoiceInferred output

Send an invoice via email. If the organization has invoiceEmailApprovalRequired enabled, the email is queued for approval. Otherwise, it's sent immediately.

Input
{
  invoiceId: string;
  recipientEmail: string;
  ccEmails?: Array<string> | undefined;
  personalMessage?: string | undefined;
}
Output
{
  success: boolean;
  error: string;
} | {
  invoiceId: string;
  recipientEmail: string;
  queued: boolean;
  queueId?: string | undefined;
  message: string;
  success: boolean;
  error?: undefined;
}