Skip to main content

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.

AspectOption A — File dropOption B — Direct API push
You produceTwo CSV files per deliveryThe same two CSV files, posted to a REST API
You deliver toYour dedicated drop-off path on the encrypted ESB file share — the only supported landing location. The path identifies your system; routing is handled for youTwo complete pre-built URLs (one accounts, one entitlements), already wired to your system's source
Auth you needShare/folder credentials, provided through the standard secret-distribution processOAuth client credentials (Client ID + Secret), scoped to your system, provided the same way
Capri-side processingA monitored script watches the ESB drop-off, validates the schema, and uploads to ISC — you never see this layerNone — your push lands directly in ISC
Failure visibilityRejection email comes back to you with the ISC error messageYou monitor your side; ISC-side failures are monitored for you
Best forTeams without engineering capacity for API work; producers where a human runs the exportTeams with DevOps maturity; systems where a scheduled CSV export already exists in a pipeline
Default✅ Start hereMigrate here once your automation is stable

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:

  1. Produce the two files per the File Specification — entitlements and accounts together.
  2. 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).
  3. Write atomically: write to a temp name, then rename — the pickup must never catch a half-written file.
  4. 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 fragmentWhat it meansFix
Column: "…" is unknownA column name not in the source's declared schemaDrop the column, or agree a schema addition first
Column: "…" is missingA required column is absentAdd 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 UnauthorizedAn upload credential expiredNot 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:

  1. Expand multi-value cells into repeated rows. The connector has no multi-value delimiter setting: a ;-joined groups cell loads as one entitlement literally named JC_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 same id, merged on the way in:

    id,name,groups
    JDOEJC,Jane Doe,JC_HFM_Submitter_Americas
    JDOEJC,Jane Doe,JC_HFM_Viewer_UK

    Do 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).

  2. 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 internal created, 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.

  3. Strip the governance columns from what you POST. owner, requestable, and privileged are 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

HTTPMeaningAction
400Schema mismatch (unknown/missing column) or malformed CSVRead the body, fix the file, retry
401Bad or expired tokenRefresh the token, retry
403Credential lacks rights on this sourceNot your side — the credential gets re-scoped
404URL wrong (usually an accidental edit)Re-copy the URL from the credentials package
429Rate limitedExponential backoff, retry
500ISC internal errorRetry; 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:

  1. A per-source onboarding ticket is opened; you're tagged as primary contact.
  2. You pick a delivery option — file drop or API push.
  3. You receive the credentials package for the option you picked.
  4. You and the IAM team agree the CSV schema — which columns, employeeId always required.
  5. You agree the cadence — daily by default; see Refresh Cadence.
  6. You deliver the first test file — to the non-production tenant, so keep real sensitive attribute values out of test extracts where you can.
  7. The test file is reviewed; schema and data issues are iterated with you.
  8. You switch on the production cadence.
  9. 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.
  10. Sign-off after the clean streak; your source is certified and the legacy feed is retired at cutover.

Support and escalation

QuestionWhere 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 questionsDharani 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 schemaThe 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 optionsThe IAM team — format is identical, so it's a credentials and runbook update
We're decommissioning this systemThe IAM team + program governance — it changes the cutover sequence