How to Export Data from Certinia: Methods, API Limits & Portability
Export Certinia data using Salesforce Bulk API 2.0, Data Loader, or REST API. Covers namespace prefixes, API limits, extraction order, and migration-ready export steps.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,500+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
How to Export Data from Certinia: Methods, API Limits & Portability
TLDR: Certinia has no standalone "Export All" button — it runs as managed packages on Salesforce, so every export method is a Salesforce export method. Your primary paths are the Data Export Service (weekly/monthly CSV dump), Salesforce Data Loader (SOQL-driven, up to 5M records), REST API, and Bulk API 2.0 (up to 100M records/day). The catch: Certinia objects live under namespaced prefixes (c2g__, pse__, fferpcore__), the relational hierarchy is complex, and Salesforce enforces a rolling 24-hour API limit starting at 100,000 requests for Enterprise Edition. A migration-ready extract covers five separate layers — transactional records, reference data, file binaries, deleted/history data, and metadata — none of which the native tools handle in one step.
Certinia (formerly FinancialForce) is a Salesforce-native ERP and Professional Services Automation (PSA) platform. Unlike standalone ERPs with their own export tooling, Certinia stores everything — financial transactions, projects, timecards, billing documents, revenue schedules — as custom objects inside your Salesforce org.
Much like exporting data from Salesforce Financial Services Cloud, that architectural choice has a direct consequence: you export Certinia data the same way you export any Salesforce data. But treating a Certinia extraction like a standard Salesforce CRM export is a path to data corruption and orphaned records. Certinia relies on managed packages, custom objects, and complex junction objects to enforce accounting rules and PSA workflows. If you are migrating off Certinia to NetSuite, QuickBooks, or another platform, you need an extraction strategy that respects namespace prefixes, relational dependencies, and Salesforce API limits.
This guide covers every extraction method, the exact limits you will hit, namespace-specific complications, extraction order, common failure modes with their symptoms, and the gaps that catch teams mid-migration.
Certinia's Data Model: What You're Actually Exporting
Before running any export, you need to understand how Certinia stores data. Salesforce provides the platform layer, while Certinia provides packaged business applications for finance, services, billing, and related operating processes. The applications run in the same org, but you need a design for ownership, field access, automation, reporting, and integration.
In a Salesforce-native model, the application stores data in standard and managed-package custom objects inside the org. The package vendor controls parts of the managed metadata, while your team controls configuration, custom metadata, Flow, reports, permission sets, and any custom extension objects you add.
Certinia ships as multiple managed packages, each with its own namespace prefix:
| Namespace Prefix | Product Area | Example Objects |
|---|---|---|
c2g__ |
FinancialForce Accounting (FFA) | c2g__codaInvoice__c, c2g__codaTransaction__c, c2g__codaJournal__c, c2g__codaTransactionLineItem__c |
pse__ |
Professional Services Automation (PSA) | pse__Proj__c, pse__Timecard__c, pse__Assignment__c, pse__Milestone__c, pse__Expense_Report__c |
fferpcore__ |
Foundations / ERP Core | fferpcore__Company__c, fferpcore__BillingDocument__c, fferpcore__BillingDocumentLineItem__c |
ffrr__ |
Revenue Recognition | Revenue recognition schedules, rules, and performance obligations |
ffbext__ |
Billing Extensions | Billing schedules, revenue objects, contract line items |
Note that many FFA object names include the word "coda" (e.g., c2g__codaInvoice__c), which is a legacy naming convention from Certinia's predecessor product — the actual namespace prefix is c2g__. If you have any custom code using the FFA credit term fields, note that the API names of the Foundations fields are prefixed with fferpcore__ instead of c2g__. This kind of prefix overlap between legacy FFA objects and newer Foundations objects is a common source of confusion during exports.
Namespace matters for every query. Every SOQL query, Data Loader configuration, and API call must include the full namespaced API name. SELECT Id, Name FROM Proj__c will fail. You need SELECT Id, Name FROM pse__Proj__c. Miss the prefix, and your export returns nothing — or hits an unrelated custom object with the same base name.
A typical Certinia org contains 50–200+ namespaced custom objects across these packages, plus custom objects your team has added. The first step in any export project is running a metadata describe call or using Salesforce Object Manager to catalog every installed object and its namespace.
Checking your installed package versions: Navigate to Setup → Installed Packages to see the current version of each Certinia managed package. Object API names and available fields differ across Certinia releases. For example, billing-related objects introduced in recent Certinia releases may not exist in orgs still running older FFA package versions. Confirm your exact package versions before writing extraction queries — a SOQL query referencing a field added in a newer package version will throw INVALID_FIELD on older orgs.
Which Export Method Should You Use?
Before diving into each method's mechanics, use this decision framework to select the right approach:
Branch 1 — I need a one-time backup before a major change: → Use the Data Export Service (Setup → Data Export). Low effort, captures all objects. Limitations: flat CSV with no relational integrity, timing is not controllable, formula fields excluded. Acceptable for point-in-time snapshots.
Branch 2 — I am migrating off Certinia to another ERP: → Use Bulk API 2.0 for record data (parent objects first, children second). Build a separate ContentVersion API pipeline for file binaries. Export metadata via SFDX/Metadata API. Handle deleted records and field history as a distinct workstream. Do not use Data Export as your primary migration extract — flat CSVs lose relationships.
Branch 3 — I need ongoing replication or a live cutover window: → Use Bulk API 2.0 for initial load, then Change Data Capture (CDC) for incremental sync. CDC subscriptions cover up to 2,000 entities per org. Enable CDC on each Certinia object you need to replicate before starting — you cannot retroactively capture changes. Consume the event stream via CometD or Pub/Sub API.
Branch 4 — I need targeted ad-hoc pulls or debugging: → Use REST API with SOQL for JSON output, or Data Loader for CSV output on specific objects.
Method 1: Salesforce Data Export Service
The built-in Data Export Service (Setup → Data Export) is the lowest-effort option. It produces a ZIP archive of CSV files for every object in your org, including all Certinia namespaced objects.
You can export data from Salesforce either manually or on an automatic schedule. The data is exported as comma-separated values (CSV) files. Data export tools provide a convenient way to obtain a copy of your Salesforce data, either for backup or for importing into a different system.
Frequency limits: Weekly exports are available once every 7 days in Enterprise, Performance, and Unlimited Editions. Monthly exports are available once every 29 days in Professional Edition.
Key constraints:
- After Salesforce generates the export files, they stay available for 48 hours. Once this window ends, the files are automatically deleted.
- If you start a new export — manual or scheduled — Salesforce immediately deletes all files from the previous export, even if the earlier export is still within the 48-hour window.
- Salesforce does not provide an SLA for completion. Export jobs may take several days or longer if system queues are busy.
- Data Export does not run in sandbox orgs or in orgs in read-only mode. This means your rehearsal plan in sandbox cannot rely on this service.
- A full export is a flattened snapshot. It captures records but not relationships, automation, or metadata.
- Formula fields and roll-up summary fields are excluded from export. These fields are computed at query time from stored values rather than persisted in the database. This means any Certinia calculated totals (e.g., roll-up billing amounts on projects) will not appear in the CSV — you must recompute them from the underlying line items.
- The Include all data checkbox selects the objects that exist when you check it. If you add a new Certinia module or custom object later, you must reselect it.
When to use it: Quick backup before a major change, compliance archiving, or rough inventory of data volumes. Not suitable for migration because object relationships are lost in flat CSV output and timing is not controllable.
Method 2: Salesforce Data Loader
Salesforce Data Loader is a desktop client that connects via the Salesforce API and exports records object-by-object using SOQL queries.
Data Loader supports importing and exporting up to 5 million records from CSV files or a database connection. It offers an easy-to-use wizard interface for interactive use as well as a command-line interface for automated batch operations.
SOQL Examples for Certinia Objects
Extracting FFA accounting transactions:
SELECT Id, Name, c2g__TransactionType__c, c2g__DocumentNumber__c,
c2g__TransactionDate__c, c2g__Account__c, c2g__Dimension1__c,
c2g__HomeValue__c, c2g__DualValue__c, c2g__DocumentCurrency__c,
CreatedDate, LastModifiedDate
FROM c2g__codaTransaction__c
WHERE c2g__TransactionDate__c >= 2024-01-01
AND IsDeleted = false
ORDER BY c2g__TransactionDate__c DESCExtracting PSA projects:
SELECT Id, Name, pse__Project_Status__c, pse__Start_Date__c,
pse__End_Date__c, pse__Bookings__c, pse__Billings__c,
pse__Region__c, pse__Project_Manager__c,
pse__Account__c, Account.Name
FROM pse__Proj__c
WHERE pse__Is_Template__c = false
AND IsDeleted = falseExport vs. Export All
Data Loader has two export modes. Export returns only current, active records. Export All returns both active and soft-deleted records (records in the Recycle Bin). This matters for archived Tasks and Events, soft-deleted Certinia records, and recovery scenarios. Use Export All deliberately — exporting deleted voided invoices into a migration can inflate financial totals.
Always include the Id field. Salesforce record IDs are the only reliable way to re-establish parent-child relationships between exported objects. For any migration, export the Id and all lookup/master-detail relationship fields for every object. Use 18-character IDs (Salesforce returns these by default via API) rather than 15-character IDs, which are case-sensitive and can collide.
Key limitations:
- Data Loader consumes your org's daily API request allocation — each SOQL query is one or more API calls depending on result size.
- Output is flat CSV — no nested relationships, no binary attachments inline. Salesforce explicitly states Data Loader does not support nested child subqueries, so you cannot pull a full parent-child tree in one export.
- To automate tasks in Salesforce Data Loader, you must use a command-line interface (CLI). CLI automation is ideal for large-scale, repetitive tasks without manual intervention, but requires more technical setup.
- A standard Certinia PSA implementation uses over 40 distinct custom objects. A full ERP implementation uses even more. Running 80+ manual Data Loader exports, managing the CSV files, and ensuring no data changed between the first and last export is highly error-prone.
Method 3: REST API and SOQL
For programmatic extraction, the Salesforce REST API runs SOQL queries and returns records as JSON. This is the preferred method for custom migration scripts at small-to-medium scale.
Base endpoint:
GET /services/data/v61.0/query?q=SELECT+Id,Name+FROM+pse__Proj__c
The response includes a nextRecordsUrl for pagination (default page size is 2,000 records). Follow the cursor until done: true.
OAuth Authentication for the Integration User
Before making any API calls, your integration user needs a valid access token. For server-to-server extraction scripts, use the OAuth 2.0 JWT Bearer Flow (no user interaction required):
# Exchange a signed JWT for an access token
curl -X POST https://login.salesforce.com/services/oauth2/token \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=$SIGNED_JWT"For interactive use during development, the Username-Password flow works, but is deprecated for production integrations. The JWT Bearer Flow requires a connected app with a certificate uploaded to Salesforce and the integration user pre-authorized. Store the resulting access_token — it expires after the session timeout period configured in your org (default 2 hours for most orgs, configurable to 24 hours).
REST API Limits That Affect Certinia Exports
This is the total number of API calls to the REST API, the SOAP API, the Bulk APIs, and the Connect API that your org is entitled to within a rolling 24-hour period. For Enterprise Edition, this starts at 100,000 requests per 24-hour period and scales with user licenses (approximately +1,000 requests per standard user license). You can also purchase additional API calls in increments ranging from 200 through 10,000 per 24-hour period.
API limit planning formula for Certinia migrations:
Estimated API calls = (Total records / 2,000) per object × Number of objects
+ (Number of files × 1 call each for binary download)
+ Buffer for retries and status checks (10-15%)
For an org with 500,000 transaction line items across 80 objects plus 10,000 attached files:
- Record queries: ~250 calls for transaction lines + ~200 calls across other objects
- File downloads: ~10,000 calls
- Total: ~10,450+ calls — well within 100K daily limit if run alone, but will compete with live integrations.
| Limit | Value | Notes |
|---|---|---|
| Daily API requests (Enterprise base) | 100,000 / 24 hrs | + ~1,000 per user license |
| Concurrent long-running requests | 25 (production) | Requests taking 20+ seconds |
| SOQL query result size | 2,000 records/page | Follow nextRecordsUrl for pagination |
| Single API call timeout | 10 minutes | Queries against large Certinia objects can hit this |
| API version minimum | v31.0+ | Versions 21.0–30.0 were retired June 2025 |
Shared API pool. Your Certinia export shares the same API quota with every other integration in the org — marketing automation, support tools, BI connectors, middleware. A full Certinia extraction during business hours can starve other integrations. Check current usage via GET /services/data/v61.0/limits before starting a large export. Schedule large extractions during off-peak hours.
Method 4: Bulk API 2.0 (Large-Scale Extraction)
For orgs with hundreds of thousands or millions of Certinia records, Bulk API 2.0 is the only practical extraction method. It is designed for asynchronous processing of massive datasets.
Bulk API 2.0 is a RESTful API that allows you to perform large-scale data operations on Salesforce objects, including query, insert, update, and delete. It is designed to simplify the process of creating and managing bulk jobs and to improve the performance and reliability of bulk data processing.
Bulk API 2.0 Limits
| Limit | Value | Notes |
|---|---|---|
| Records per 24-hour period | 100,000,000 | Covers virtually any Certinia org |
| Batches per 24-hour period | 15,000 (shared with Bulk API 1.0) | Only ingest jobs consume batches; query jobs do not |
| Data per ingest job | 150 MB | For uploads; query result downloads are not size-limited per job |
| Query job batch consumption | 0 batches | Query jobs don't count against the 15,000 batch limit |
The last point is significant for exports: Bulk API 2.0 query jobs don't count against the 15,000 batch limit. They do count against your daily API request allocation, but the overhead is minimal — one call to create the job, polling calls to check status, and one or more calls to download results.
Example: Bulk Query for Certinia Invoices
# Step 1: Create a query job
curl -X POST https://yourorg.my.salesforce.com/services/data/v61.0/jobs/query \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operation": "query",
"query": "SELECT Id, Name, c2g__Account__c, c2g__InvoiceDate__c, c2g__InvoiceTotal__c, c2g__OutstandingValue__c, c2g__InvoiceStatus__c FROM c2g__codaInvoice__c WHERE IsDeleted = false"
}'
# Step 2: Poll for completion (replace {jobId} with the returned id)
curl https://yourorg.my.salesforce.com/services/data/v61.0/jobs/query/{jobId} \
-H "Authorization: Bearer $ACCESS_TOKEN"
# Step 3: Download results (when state = "JobComplete")
curl https://yourorg.my.salesforce.com/services/data/v61.0/jobs/query/{jobId}/results \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-o invoices.csvResults come back as CSV. For objects with 1M+ records (common for c2g__codaTransactionLineItem__c in mature orgs), Salesforce automatically chunks results into multiple locators you download sequentially using the Sforce-Locator response header.
For command-line automation, Salesforce CLI wraps Bulk API 2.0 cleanly:
sf data export bulk --target-org certinia-prod \
--query "SELECT Id, Name, SystemModstamp FROM c2g__codaInvoice__c WHERE IsDeleted = false ORDER BY SystemModstamp, Id" \
--output-file invoices.csv --result-format csvUse --all-rows when you need soft-deleted records. Avoid OFFSET-style pagination on large objects — as OFFSET forces Salesforce to scan and discard rows before returning results, performance degrades linearly at scale. Use keyset pagination based on SystemModstamp plus Id for reliable, performant incremental extraction.
Query Timeout and Relationship Traversal Limits
Certinia objects often have dozens of lookup relationships. SOQL queries with more than 5 relationship traversals (__r notation) or nested subqueries hitting the 100,000-row governor limit will cause Bulk API jobs to fail with a timeout or governor limit error. The symptom is a job that transitions to Failed state with QUERY_TIMEOUT or UNABLE_TO_LOCK_ROW in the error detail.
Stick to flat queries on single objects and handle joins in your target database or ETL pipeline. For example, rather than:
-- Avoid: complex relationship traversal
SELECT Id, pse__Project__r.Name, pse__Project__r.pse__Account__r.Name
FROM pse__Timecard__cExport flat and join later:
-- Better: flat query, join in ETL
SELECT Id, pse__Project__c, pse__Time_Period_Start__c, pse__Monday_Hours__c
FROM pse__Timecard__c WHERE IsDeleted = falseMethod 5: Change Data Capture for Ongoing Replication
If your migration spans multiple days or you need ongoing replication to a target system, Change Data Capture (CDC) is the mechanism for capturing incremental changes after the initial bulk extract.
How CDC works with Certinia objects:
- Navigate to Setup → Change Data Capture and enable CDC for each Certinia object you need to replicate (e.g.,
c2g__codaInvoice__c,pse__Proj__c). - Subscribe to the change event channel via CometD or the Salesforce Pub/Sub API.
- Each change event contains the record Id, changed fields, and change type (CREATE, UPDATE, DELETE, UNDELETE).
CDC limits:
- Up to 2,000 entities can have CDC enabled per org.
- CDC events are retained for 72 hours — if your consumer is offline longer than that, you will miss events and must re-query those objects via SOQL.
- CDC does not capture changes made by Data Loader imports or Bulk API operations by default (check the
ChangeEventHeader.changeOriginfield to filter by source). - You cannot retroactively capture changes — CDC only tracks events from the moment it is enabled. Enable CDC before starting your initial bulk extract, not after.
CDC and Certinia managed packages: CDC can be enabled on most Certinia custom objects, but some managed package objects with restrictive sharing models may not emit events for all field changes. Test CDC coverage for your specific objects in a sandbox before relying on it for production cutover.
Method 6: Salesforce Reports and Certinia Financial Report Builder
Salesforce reports can export Certinia data if you have report types configured for the relevant objects.
When exporting a report in Lightning Experience as Formatted Report or .xlsx Details Only, you can export up to 100,000 rows and 100 columns. If a report takes 10 minutes or more to export, it times out and fails.
Certinia also has its own Financial Report Builder, which can export reports and statements in CSV, XLSX, or PDF. Board packs can bundle multiple reports into a single export. Certinia supports exporting report-definition configuration sets as CSV or JSON from the Share Report Definitions page.
These report exports are presentation outputs, not raw data extracts. They can flatten tables, apply filters, or represent calculated views that don't match the underlying Certinia objects. Useful for finance teams validating an API extract, not for replacing it.
What the Standard Methods Don't Export
Every method above exports record data — the rows and columns in Certinia objects. A complete extraction for migration also requires handling three additional layers.
Attachments and Files
Certinia records frequently have Salesforce Files (ContentDocument/ContentVersion) or legacy Attachments linked via ContentDocumentLink. Statements of work on Projects, receipt images on Expense Reports — these are stored in Salesforce's standard file architecture, not in the Certinia objects themselves.
Just as you would when exporting data from Salesforce Service Cloud, exporting files requires querying three separate Salesforce objects:
ContentDocumentLink— the junction that links a file to a Certinia record.ContentDocument— the parent container for file versions.ContentVersion— the actual file binary and metadata.
Extraction steps:
-- Step 1: Find files linked to invoices
SELECT Id, ContentDocumentId, LinkedEntityId
FROM ContentDocumentLink
WHERE LinkedEntityId IN (
SELECT Id FROM c2g__codaInvoice__c WHERE IsDeleted = false
)
-- Step 2: Get file metadata
SELECT Id, ContentDocumentId, VersionData, Title, FileExtension, ContentSize
FROM ContentVersion
WHERE ContentDocumentId IN ('...')
AND IsLatest = trueThen download each file's binary via:
GET /services/data/v61.0/sobjects/ContentVersion/{id}/VersionData
This is one API call per file. For orgs with thousands of invoice attachments, this is where API limits become a real constraint. Batch these requests or use a dedicated extraction script that respects the daily API limit.
Data Loader can export file metadata but not the actual file binaries. For full file portability, use the Data Export Service with file options enabled or build a custom download pipeline.
Rich-text image trap. Images embedded in rich-text fields are stored separately from the record. In Data Export, they appear in the "Other Uploaded Collateral" folder. You need ContentReference.csv, RichTextAreaFieldData.csv, and the source object CSV to map them back to parent records. If you only export the source object CSV, embedded images will be missing from your migration with no error.
Metadata and Configuration
Certinia's behavior is controlled by custom settings, custom metadata types, and managed package configuration. Querying custom metadata does not count against SOQL governor limits.
However, much of the managed package metadata is read-only and vendor-controlled. You cannot export Certinia's internal Apex classes, triggers, or validation rule logic. What you can export:
- Custom metadata type records (via SOQL or Metadata API)
- Custom settings values (via SOQL on the settings object)
- Page layouts, permission sets, and custom fields you've added (via Metadata API / SFDX)
- Flow and Process Builder automations you've built
- Certinia report definitions (via the Share Report Definitions page)
For your own Salesforce customizations, use sf project retrieve start or the Metadata API. Be aware of managed package limits: protected custom metadata in managed packages is not accessible like subscriber-owned metadata, and listMetadata() has gaps for managed package components.
Deleted and Archived Records
Salesforce's Recycle Bin retains deleted records for 15 days. The queryAll operation in Bulk API and Data Loader's Export All mode include soft-deleted records within this window. Once records are fully purged (manually or automatically after 15 days), they are gone unless you have a third-party backup.
Field history retention is time-bounded: without Field Audit Trail enabled, Salesforce retains standard field history for up to 18 months for most objects, and this window varies by object type and edition. If your Certinia migration has audit or compliance requirements, export history objects (e.g., c2g__codaInvoice__History) early and confirm whether Field Audit Trail is enabled for sensitive financial fields. Field Audit Trail extends retention up to 10 years for fields you designate, but must be configured before the audit period — it does not backfill.
The Extraction Order: Maintaining Relational Integrity
Data portability is not just about getting the data out — it's about keeping the relationships intact. Certinia data is highly relational. If you export child records before parent records, or if you fail to map the Salesforce 18-character IDs, your target system will reject the import.
Extract objects in strict hierarchical order, parents before children.
PSA Data Hierarchy
User / Account / Contact (Salesforce standard objects)
↓
pse__Region__c / pse__Practice__c / pse__Group__c (RPG hierarchy)
↓
pse__Proj__c (Projects)
↓
pse__Milestone__c / pse__Project_Phase__c
↓
pse__Assignment__c (links Contacts/Resources to Projects)
↓
pse__Timecard_Header__c
↓
pse__Timecard__c / pse__Expense_Report__c / pse__Expense__c
ERP / Financials Data Hierarchy
Financial data is even more rigid. You cannot migrate partial accounting data; it must balance.
fferpcore__Company__c / c2g__codaYear__c / c2g__codaPeriod__c
↓
c2g__codaGeneralLedgerAccount__c (chart of accounts)
↓
c2g__codaDimension1__c through c2g__codaDimension4__c (analysis dimensions)
↓
c2g__codaInvoice__c / c2g__codaPurchaseInvoice__c
↓
c2g__codaInvoiceLineItem__c
↓
c2g__codaTransaction__c / c2g__codaJournal__c
↓
c2g__codaTransactionLineItem__c
Key relationship chains to document before extraction:
c2g__codaInvoice__c→c2g__codaInvoiceLineItem__c→c2g__codaTransaction__c→c2g__codaTransactionLineItem__cpse__Proj__c→pse__Assignment__c→pse__Timecard_Header__c→pse__Timecard__cfferpcore__BillingDocument__c→fferpcore__BillingDocumentLineItem__c
The soft-delete trap. When querying Certinia data via the REST API or Bulk API, always include WHERE IsDeleted = false in your SOQL queries unless you specifically need deleted records. Otherwise, you will extract deleted timecards and voided invoices, artificially inflating your financial totals in the target system. This is the single most common data quality error in Certinia extractions.
Field-Level Security and Visibility Constraints
One of the most common failure modes during a Certinia extraction is missing data caused by Salesforce permission models — and it happens silently.
Even if you use a System Administrator account, Field-Level Security (FLS) can hide specific Certinia fields from the API. If the integration user executing the Bulk API job does not have explicit "Read" access to a custom field (e.g., pse__Billed__c), the API will simply omit that field from the CSV or JSON response. It will not throw an error — the data will just be missing.
Before extracting: Create a dedicated Salesforce integration user with the "View All Data" system permission. Ensure FLS is set to "Visible" for all c2g__, pse__, fferpcore__, ffrr__, and ffbext__ fields. Use a dedicated permission set rather than modifying a human admin profile, so you can audit and revoke access cleanly after the migration.
Use a dedicated, non-human Salesforce integration user with OAuth Client Credentials (client_credentials grant) rather than username-password authentication for production extractions. This avoids session expiry issues during long-running bulk jobs.
To verify FLS coverage before running a full extraction:
-- Check which fields are accessible for a given object
SELECT Id, SobjectType, Field, PermissionsRead
FROM FieldPermissions
WHERE SobjectType = 'pse__Proj__c'
AND PermissionsRead = false
AND Parent.ProfileId = '[your integration user profile id]'Any field returned by this query with PermissionsRead = false will be silently omitted from your export.
Error Taxonomy: What Actually Breaks and Why
The following are the most common failure modes in Certinia extractions, with their symptoms and resolutions:
| Error / Symptom | Cause | Resolution |
|---|---|---|
INVALID_FIELD: No such column 'Proj__c' |
Missing namespace prefix in SOQL | Change to pse__Proj__c — always include full namespace |
INVALID_FIELD: c2g__SomeField__c on older org |
Field added in a newer Certinia package version | Check installed package version; query against actual installed schema via describeGlobal() |
Job transitions to Failed with QUERY_TIMEOUT |
Too many relationship traversals or large object with complex filter | Simplify query to single object; remove __r traversals; use flat query + ETL-side join |
| Fields missing from CSV output with no error | Field-Level Security blocking read access for integration user | Grant FLS Read on affected fields; verify via FieldPermissions query above |
REQUEST_LIMIT_EXCEEDED |
Daily API call limit exhausted | Schedule extractions off-peak; check /limits endpoint before starting; purchase additional API capacity |
UNABLE_TO_LOCK_ROW |
Concurrent writes to records being queried (active Certinia users posting transactions) | Run bulk extractions during maintenance windows or off-peak; use Bulk API which is more resilient to lock contention |
401 Unauthorized mid-job |
OAuth access token expired during long-running extraction | Use JWT Bearer Flow with a refresh mechanism; configure session timeout to maximum allowed (up to 24 hours) |
| Soft-deleted records in financial totals | Missing IsDeleted = false filter |
Always include WHERE IsDeleted = false unless explicitly extracting deleted records |
SOQL_TOO_MANY_ROWS (100,000 row governor limit) |
Complex subquery or IN clause scanning too many records | Break into multiple targeted queries; use keyset pagination instead of large IN clauses |
| Missing binary file content | Data Loader used for file export | Use ContentVersion API (/VersionData) directly; Data Loader exports metadata only |
| CDC events missing for some field changes | Some managed package fields don't emit CDC events | Verify CDC coverage per field in sandbox before production reliance; supplement with SystemModstamp-based SOQL polling |
Comparing Certinia Export Methods
| Method | Format | Record Limit | Relational Integrity | Attachments | Automation | Best For |
|---|---|---|---|---|---|---|
| Data Export Service | CSV (ZIP) | All objects | ❌ Flat files | Optional (separate files) | Weekly/monthly schedule | Backup snapshots |
| Data Loader | CSV | 5M per session | ❌ Manual rejoin via IDs | ❌ Separate workflow | CLI batch mode | Object-by-object pulls |
| REST API (SOQL) | JSON | 2,000/page, paginated | ✅ Via relationship queries | ✅ Via ContentVersion | Fully scriptable | Custom scripts, small-medium volumes |
| Bulk API 2.0 | CSV | 100M records/day | ❌ Flat per job, rejoin via IDs | ❌ Separate workflow | Fully scriptable | Large-scale migration |
| Change Data Capture | JSON events | 2,000 entities max | ✅ Per-record change events | ❌ | Event-driven | Incremental sync, live cutover |
| Reports / FRB | XLSX/CSV | 100,000 rows | ❌ Flat | ❌ | Scheduled email | Ad-hoc analysis, validation |
| Metadata API / SFDX | XML/JSON | N/A (metadata only) | ✅ | N/A | CLI / CI-CD | Schema and config export |
Building a Migration-Ready Certinia Export Plan
Step 1: Set Up Access and Verify Package Versions
Create a dedicated Salesforce API-only integration user. Grant View All Data, and set FLS to Visible for all namespaced fields. Navigate to Setup → Installed Packages to record the exact version of each Certinia managed package. Query your org's schema via describeGlobal() and filter for c2g__, pse__, fferpcore__, ffrr__, and ffbext__ prefixes to build your authoritative object list — do not rely on documentation alone, as available objects and fields depend on your exact installed versions.
Step 2: Enable CDC (If Doing Live Cutover)
If your migration requires a live cutover where Certinia stays operational during extraction, enable Change Data Capture on all objects before starting the initial bulk export. This ensures you can capture changes that occur while the bulk extract runs. CDC events persist for 72 hours — size your extraction timeline to complete the initial load and delta replay within that window.
Step 3: Map Relationships
For each object, document all lookup and master-detail relationship fields. These are your foreign keys. Split your object list into: (1) master data / reference objects, (2) transactional records, (3) history objects, and (4) file/attachment references.
Step 4: Export Record Data via Bulk API 2.0
Create query jobs for each object, starting with parent objects and working down to children. Always include Id, all relationship fields, CreatedDate, LastModifiedDate, and SystemModstamp. Always include WHERE IsDeleted = false unless explicitly extracting deleted records. Use keyset pagination (ORDER BY SystemModstamp, Id) for large objects.
Step 5: Export Attachments, Files, and History Separately
Query ContentDocumentLink for each parent object, then download binary content via the ContentVersion API (/VersionData endpoint). Export deleted records and field history with their own dedicated process — do not assume the main record export covers them. Export c2g__codaInvoice__History, pse__Proj__History, and other audit trail objects explicitly.
Step 6: Export Metadata
Use SFDX or the Metadata API to pull custom fields, page layouts, validation rules, permission sets, and custom metadata types. Export Certinia report definitions via the Share Report Definitions page. Note which components are vendor-managed (read-only) versus subscriber-managed (exportable).
Step 7: Run Delta Sync and Validate
For migrations spanning multiple days, apply incremental SOQL filtered on LastModifiedDate > [last_extraction_timestamp] or consume CDC events until cutover. Validate by reconciling: record counts per object, sum of c2g__HomeValue__c by period and company (debits must equal credits), attachment counts per parent record type, and a sample of file-to-record link mappings. Confirm that every lookup ID in child records has a matching parent record in your exported dataset.
For a deeper look at why flat CSV exports struggle with relational data like Certinia's, see Using CSVs for SaaS Data Migrations.
Edge Cases and Failure Modes
Multi-currency orgs: Certinia accounting often runs in multi-currency mode. Transaction amounts are stored in document currency (c2g__DocumentValue__c), home currency (c2g__HomeValue__c), and dual currency (c2g__DualValue__c) fields. If you export only one value field, your financial data is incomplete and will not reconcile. Export all three currency fields plus the document currency code field for every monetary amount.
Company-dependent objects: Many FFA objects are scoped to a specific c2g__OwnerCompany__c. If your org runs multiple Certinia companies, partition exports by company (WHERE c2g__OwnerCompany__c = ' [company_id]') or risk mixing financial data across entities — a fatal error for accounting integrity.
Junction objects and many-to-many relationships: Certinia uses junction objects to handle many-to-many relationships (e.g., assigning multiple resources to multiple projects via pse__Assignment__c). Target systems like QuickBooks do not handle many-to-many relationships natively, requiring you to flatten or denormalize during the ETL process.
Salesforce ID mapping: Every Certinia record relies on Salesforce's 18-character alphanumeric IDs. Your target system uses its own primary keys. Maintain a mapping table throughout migration — a lookup from Salesforce ID to target system ID for every parent object — and apply it when loading child records. Without this table, child records will reference non-existent parents in the target system.
Multi-company intercompany transactions: If you use Certinia's multi-company framework, intercompany transactions link across company definitions within a single org. Migrating this requires logic to split these transactions into separate company-specific entries in the target ERP, each with the correct intercompany payable/receivable treatment.
Governor limits on complex queries: SOQL queries with multiple relationship traversals or large IN clauses can hit Salesforce's 100,000-row-per-transaction governor limit. Break complex queries into targeted, single-object pulls and perform all joins outside of Salesforce.
Certinia version differences: Object availability and field API names vary across Certinia package versions. For example, certain ffrr__ revenue recognition fields were introduced in specific release versions and will return INVALID_FIELD on older orgs. Always validate your query field list against the actual installed schema, not against current Certinia documentation.
How Certinia Compares to Other ERP Exports
Certinia's Salesforce-native architecture is both an advantage and a constraint. You get access to Salesforce's mature, well-documented API ecosystem — Bulk API 2.0's 100M records/day throughput is far higher than most standalone ERP export capabilities. You also inherit Salesforce's API limits, and the namespaced object model adds a discovery step that standalone ERPs don't require.
Compare this to platforms like NetSuite, which has its own SuiteScript/SuiteTalk export mechanisms with per-request concurrency limits, or QuickBooks Online, which has tighter API rate limits (500 requests/minute) but a simpler data model. For a direct architecture comparison, see our QuickBooks vs Certinia guide.
The critical difference with Certinia versus standalone ERPs: there is no vendor-provided migration export utility. NetSuite has a Data Migration Assistant and CSV import/export tools purpose-built for migrations. Certinia's extraction is entirely API-driven, requiring engineering work that NetSuite's tooling handles out of the box.
When to Bring in Help: A Decision Matrix
| Scenario | Complexity | Recommended Approach |
|---|---|---|
| Single object export for reporting | Low | Data Loader or REST API, self-service |
| Full org backup before Certinia config change | Low-Medium | Data Export Service |
| Migration of PSA data only (no financials) | Medium | Bulk API 2.0 for ~40 PSA objects; manageable with one engineer over 1–2 weeks |
| Migration of financials only (no PSA) | Medium-High | Bulk API 2.0 + accounting integrity validation; requires ERP accounting knowledge to verify balance |
| Full Certinia migration (PSA + Financials + Files) | High | Bulk API 2.0 + ContentVersion pipeline + CDC for delta + metadata export; 50–100+ objects; typically 4–8 weeks of engineering |
| Multi-company Certinia org migration | Very High | Intercompany transaction splitting + per-company validation; requires Certinia accounting expertise |
| Zero-downtime cutover with live Certinia org | Very High | Bulk initial extract + CDC delta + cutover validation; requires careful CDC window management |
A Certinia data export is straightforward for a single object. It becomes a real engineering project when you need complete relational extraction across 50+ namespaced objects, financial data integrity (debits equal credits, multi-currency values consistent, period-end balances reconcile), attachment extraction at scale, zero-downtime migration, or target system schema mapping.
The repeat failure pattern in Certinia migrations: teams export Certinia reports, assume they have the data, and only discover the gaps when they try to load a target ERP. The gaps are predictable — missing soft-deleted record exclusions, missing file binaries, missing multi-currency fields, missing intercompany transaction handling, and missing parent-before-child extraction order. The safer approach is table-level export for records, a separate file pipeline, explicit handling for deleted and history data, and a distinct metadata workstream.
Frequently Asked Questions
- How do I export all data from Certinia?
- Certinia has no built-in 'Export All' button. Use Salesforce's Data Export Service (Setup → Data Export) for a full CSV snapshot, or use Bulk API 2.0 for a structured, object-by-object extraction. All Certinia objects use namespaced prefixes (c2g__, pse__, fferpcore__) that must be included in every SOQL query.
- What API limits apply when exporting Certinia data?
- Certinia runs on Salesforce, so Salesforce API limits apply. Enterprise Edition starts at 100,000 REST/SOAP API calls per rolling 24-hour period (plus 1,000 per user license). Bulk API 2.0 allows up to 100 million records per day, and query jobs don't count against the 15,000-batch daily limit.
- Why are fields missing from my Certinia API export?
- This is almost always caused by Field-Level Security (FLS) settings in Salesforce. If the integration user lacks explicit read access to a namespaced Certinia field, the API will silently omit it from the export without throwing an error.
- What happens to my data if we uninstall the Certinia managed package?
- Uninstalling a Salesforce managed package permanently deletes all custom objects, fields, and data associated with that package. You must perform a complete data extraction before uninstalling.
- Can Data Loader export Certinia file attachments?
- Data Loader can export file metadata (ContentDocumentLink, ContentVersion records) but not the actual file binaries. To download file content, use the ContentVersion VersionData REST API endpoint or the Data Export Service with file options enabled.