Delivery Options
Two supported ways to get your files to ISC. The File Specification is identical for both — only the transport differs, and you can switch later with a credentials-and-runbook update, no format change.
| Aspect | Option A — File drop | Option B — Direct API push |
|---|---|---|
| You produce | Two CSV files per delivery | The same two CSV files, posted to a REST API |
| You deliver to | Your dedicated drop-off path on the encrypted ESB file share — the only supported landing location. The path identifies your system; routing is handled for you | Two complete pre-built URLs (one accounts, one entitlements), already wired to your system's source |
| Auth you need | Share/folder credentials, provided through the standard secret-distribution process | OAuth client credentials (Client ID + Secret), scoped to your system, provided the same way |
| Capri-side processing | A monitored script watches the ESB drop-off, validates the schema, and uploads to ISC — you never see this layer | None — your push lands directly in ISC |
| Failure visibility | Rejection email comes back to you with the ISC error message | You monitor your side; ISC-side failures are monitored for you |
| Best for | Teams without engineering capacity for API work; producers where a human runs the export | Teams with DevOps maturity; systems where a scheduled CSV export already exists in a pipeline |
| Default | ✅ Start here | Migrate here once your automation is stable |
Option A — File drop (recommended default)
Files are dropped on the ESB file share — the one supported landing location; CSVs are not accepted by email or any other channel. What is set up for you: your drop-off path on the share, its credentials, the scheduled pickup that validates and uploads your files, and a rejection email that reaches you with the exact ISC error when a delivery fails.
What you do each delivery:
- Produce the two files per the File Specification — entitlements and accounts together.
- Encrypt with the ESB public key — an unencrypted file, or one encrypted with the wrong key, is not picked up. Dharani Kanker is the ESB contact for obtaining the key, share access, and any encryption questions (see also the Owner Guide).
- Write atomically: write to a temp name, then rename — the pickup must never catch a half-written file.
- Land before the pickup window — typically 02:00 ET; confirm the window for your system.
If your file is rejected
The rejection email carries the ISC error. The common ones:
| Error fragment | What it means | Fix |
|---|---|---|
Column: "…" is unknown | A column name not in the source's declared schema | Drop the column, or agree a schema addition first |
Column: "…" is missing | A required column is absent | Add the column — even if every value is empty |
400.1.3 Illegal value (with a row reference) | A specific row has a malformed value (wrong type, bad date) | Fix or filter that row |
401 Unauthorized | An upload credential expired | Not your side — it will be regenerated and you'll be told |
Re-deliver the corrected file; the next pickup takes it from there.
Option B — Direct API push
You receive a credentials package containing exactly two things — treat both as opaque and don't assemble URLs yourself:
- Two complete URLs, pre-wired to your system's source: one for accounts, one for entitlements (the entitlement URL carries
object-type=group). - OAuth client credentials (Client ID + Secret), scoped to your system, plus the token URL.
Authentication
Standard client-credentials grant; the token is passed as a bearer header and lives ~12 hours:
curl -s -X POST "${TOKEN_URL}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}"
# → { "access_token": "…", … }
Upload
multipart/form-data, and let your HTTP client set the Content-Type header (it needs the multipart boundary). The file part is lowercase file on both endpoints — some older docs claim the entitlement endpoint wants csvFile, but every real source built in this program has loaded with file. The entitlement URL you're given already carries the object-type=group selector; send the matching objectType form part as well (both together is the combination four production builds have verified):
# Entitlements FIRST
curl -X POST "${ENTITLEMENTS_URL}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "file=@entitlements.csv;type=text/csv" \
-F "objectType=group"
# Accounts second
curl -X POST "${ACCOUNTS_URL}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "file=@accounts.csv;type=text/csv" \
-F "disableOptimization=false"
The filename on your disk is irrelevant to ISC — only the content is read.
A successful upload returns HTTP 202 with a task object; aggregation runs asynchronously. One asymmetry for your scripting: the accounts response nests the task under .task, while the entitlements response returns the task object directly. Keep the task id either way — it pinpoints a specific run if a question ever comes up:
{ "type": "QUARTZ", "id": "af1b82086c194f89acce82e156ff6e61", "name": "Cloud Account Aggregation", … }
Pipeline steps you take over
The file-drop pipeline quietly fixes three things between your file and the API. Pushing directly means they're yours now — and none of them produce an error when wrong; each one loads cleanly and is simply broken:
-
Expand multi-value cells into repeated rows. The connector has no multi-value delimiter setting: a
;-joinedgroupscell loads as one entitlement literally namedJC_HFM_Submitter_Americas;JC_HFM_Viewer_UK— it aggregates cleanly, appears in the catalog matching nothing in your entitlement file, and once sat in a tenant for a week looking healthy. What the connector understands is one row per entitlement value, repeated rows sharing the sameid, merged on the way in:id,name,groups
JDOEJC,Jane Doe,JC_HFM_Submitter_Americas
JDOEJC,Jane Doe,JC_HFM_Viewer_UKDo the expansion with a real CSV library, not string splitting —
"Milan, IT"is an ordinary value in these files. Expect the row count to grow accordingly (one real source expands 172 accounts to 438 rows). -
Match the schema's column order exactly. ISC validates header names but maps values to attributes by position — a correct-but-reordered header loads every account with its values in the wrong attributes. Every schema attribute must be present, including the ones your extract doesn't own: the account schema's auto-added
manager(send it empty), and the entitlement schema's internalcreated,modified,entitlements,groups,permissions(empty). Omitting one shifts every column after the gap. The exact header lines for your source are part of your credentials package — use them verbatim rather than deriving your own. -
Strip the governance columns from what you POST.
owner,requestable, andprivilegedare not schema attributes — the entitlement upload doesn't accept them; they're applied to the entitlement objects through the ISC API after aggregation, on the Capri side. Keep them in the eight-column file you maintain (they're still the contract), but the version you POST carries only the schema columns — and when a governance value changes, tell your IAM contact so the ISC-side properties get re-applied.
During onboarding your first pushes go to the test tenant, where these are checked for you (concatenated-entitlement scan, row counts, correlation) before production cadence starts — but in steady state, nothing rechecks them. If your export tooling changes, re-verify all three.
Error responses
| HTTP | Meaning | Action |
|---|---|---|
| 400 | Schema mismatch (unknown/missing column) or malformed CSV | Read the body, fix the file, retry |
| 401 | Bad or expired token | Refresh the token, retry |
| 403 | Credential lacks rights on this source | Not your side — the credential gets re-scoped |
| 404 | URL wrong (usually an accidental edit) | Re-copy the URL from the credentials package |
| 429 | Rate limited | Exponential backoff, retry |
| 500 | ISC internal error | Retry; if it persists it becomes a SailPoint support ticket |
disableOptimization
ISC skips rows unchanged since the last aggregation by default (disableOptimization=false) — leave it that way. The one exception: after a correlation-rule change on your source, the first upload should pass true to force every row through the new rules. You'll be told when that applies; don't toggle it on your own, a full reprocess is slow and shows up as an anomaly.
Onboarding checklist
The path from zero to certified source:
- A per-source onboarding ticket is opened; you're tagged as primary contact.
- You pick a delivery option — file drop or API push.
- You receive the credentials package for the option you picked.
- You and the IAM team agree the CSV schema — which columns,
employeeIdalways required. - You agree the cadence — daily by default; see Refresh Cadence.
- You deliver the first test file — to the non-production tenant, so keep real sensitive attribute values out of test extracts where you can.
- The test file is reviewed; schema and data issues are iterated with you.
- You switch on the production cadence.
- Parallel-run window: your feed is reconciled against the legacy system's data daily — 14 consecutive clean days for normal sources, 30 for SOX-critical. You respond to any drift findings.
- Sign-off after the clean streak; your source is certified and the legacy feed is retired at cutover.
Support and escalation
| Question | Where it goes |
|---|---|
| Where do I deliver? What credentials? | Your assigned IAM contact, named in your onboarding ticket |
| ESB file share access, the public key, encryption questions | Dharani Kanker |
| My file was rejected — what does the error mean? | Reply to the rejection email; answered within 1 business day |
| I need a new column in the schema | The IAM team — a small schema change is hours, not weeks |
| My URL / credentials stopped working (403/404) | The IAM team — almost always a credential issue, not your CSV |
| We can't deliver tomorrow (holiday, maintenance) | Tell the IAM lead in advance. One missed day is logged, not escalated; repeated misses trigger the fallback (re-upload of your last good file on your behalf) |
| We want to switch delivery options | The IAM team — format is identical, so it's a credentials and runbook update |
| We're decommissioning this system | The IAM team + program governance — it changes the cutover sequence |