create-billing-transfer-end-customer-mappings
dci create-billing-transfer-end-customer-mappings [body]
Maps end-customer AWS accounts under a reseller's PMA to their DoiT tenant, as part of AWS
billing transfer onboarding. Reseller-only; distributors are explicitly denied (403).
Unlike POST /billingtransfer/v1/resellerhandshakes, this endpoint has no
Idempotency-Key requirement and no dryRun support.
This path is a deliberate exception to the de-hyphenation convention used by the sibling
resellerhandshakes and programmanagementaccounts paths — it stays hyphenated to match
the existing Go route and its console-facing equivalent.
Each item in the batch is processed independently; per-item outcomes are returned in
results[] with HTTP 200. Malformed items are rejected up front and reported in
invalidItems without processing any of the batch.
Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.
Reseller tenants only: distributor tenants receive 403. Each item is processed
independently and reported in results[]; if any item is malformed the API rejects
the whole batch up front and lists the offenders in invalidItems. Unlike
create-billing-transfer-reseller-handshakes, this command has no --dry-run or
--idempotency-key.
Examples
# Map end-customer AWS accounts under your reseller PMA to their DoiT customers, from a file (reseller tenants only).
dci create-billing-transfer-end-customer-mappings < mappings.json
# mappings.json
{"dpmaId": "<dpma-id>", "resellerPmaAccountId": "123456789012",
"items": [
{"ecAccountId": "210987654321", "ecCustomerId": "<customer-id>"},
{"ecAccountId": "310987654321", "ecCustomerId": "<customer-id>",
"curBasePath": "s3://acme-cur-exports/cur/"}]}
# Per-item outcomes as JSON, for scripts.
dci create-billing-transfer-end-customer-mappings --output json < mappings.json
A `results` list with one entry per item and its `status` (`mapped`, `already_mapped` or `remapped`); malformed items appear in `invalidItems` and stop the whole batch.
Request
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
dpmaId | string | yes | |
resellerPmaAccountId | string | yes | 12-digit AWS account ID of the reseller's program management account. |
items | array of object | yes | Batch items. Duplicate ecAccountId or ecCustomerId values within the batch are rejected. |
items[].ecAccountId | string | yes | 12-digit AWS account ID of the end-customer account being mapped. |
items[].ecCustomerId | string | yes | DoiT customer ID to map the end-customer account to. |
items[].curBasePath | string | Optional CUR export base path for the end-customer account. |
Raw JSON schema
{
"type": "object",
"additionalProperties": false,
"required": [
"dpmaId",
"resellerPmaAccountId",
"items"
],
"properties": {
"dpmaId": {
"type": "string"
},
"resellerPmaAccountId": {
"type": "string",
"description": "12-digit AWS account ID of the reseller's program management account.",
"example": "123456789012"
},
"items": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"description": "Batch items. Duplicate `ecAccountId` or `ecCustomerId` values within the batch are rejected.",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"ecAccountId",
"ecCustomerId"
],
"properties": {
"ecAccountId": {
"type": "string",
"description": "12-digit AWS account ID of the end-customer account being mapped.",
"example": "123456789012"
},
"ecCustomerId": {
"type": "string",
"description": "DoiT customer ID to map the end-customer account to."
},
"curBasePath": {
"type": "string",
"description": "Optional CUR export base path for the end-customer account."
}
}
}
}
}
}
Output
OK - Batch processed; see results for per-item outcomes and invalidItems for any items rejected before processing.
By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.
| Field | Type | Description |
|---|---|---|
dpmaId | string | |
resellerPmaAccountId | string | |
results | array of object | |
results[].ecAccountId | string | |
results[].ecCustomerId | string | |
results[].curBasePath | string | |
results[].status | string | One of: "mapped", "already_mapped", "remapped". |
invalidItems | array of object | Items rejected before processing. Omitted when every item passed validation. |
invalidItems[].index | integer | Zero-based position of the invalid item within the submitted batch. |
invalidItems[].resellerCustomerId | string | Present when the invalid item is a reseller-handshake batch item. |
invalidItems[].code | string | Stable machine-readable error code (e.g. duplicate_pma, duplicate_ec_account). |
invalidItems[].reason | string | Human-readable explanation of why the item is invalid. |
Raw JSON schema
{
"type": "object",
"additionalProperties": false,
"required": [
"dpmaId",
"resellerPmaAccountId",
"results"
],
"properties": {
"dpmaId": {
"type": "string"
},
"resellerPmaAccountId": {
"type": "string"
},
"results": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"ecAccountId",
"ecCustomerId",
"status"
],
"properties": {
"ecAccountId": {
"type": "string"
},
"ecCustomerId": {
"type": "string"
},
"curBasePath": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"mapped",
"already_mapped",
"remapped"
]
}
}
}
},
"invalidItems": {
"type": "array",
"description": "Items rejected before processing. Omitted when every item passed validation.",
"items": {
"type": "object",
"description": "A single batch item that failed validation before processing began.",
"additionalProperties": false,
"required": [
"index",
"code"
],
"properties": {
"index": {
"type": "integer",
"description": "Zero-based position of the invalid item within the submitted batch."
},
"resellerCustomerId": {
"type": "string",
"description": "Present when the invalid item is a reseller-handshake batch item."
},
"code": {
"type": "string",
"description": "Stable machine-readable error code (e.g. `duplicate_pma`, `duplicate_ec_account`).",
"example": "duplicate_pma"
},
"reason": {
"type": "string",
"description": "Human-readable explanation of why the item is invalid."
}
}
}
}
}
}
Errors
On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.
HTTP status to exit code mapping
| HTTP status | Exit code | Error code | Meaning |
|---|---|---|---|
| 400, 422 | 30 | VALIDATION_ERROR | The arguments or request body were rejected. Review the command's flags and payload. |
| 401 | 10 | AUTHENTICATION_FAILED | Not signed in, or the API token is invalid. Run dci login or check DCI_API_KEY. |
| 403 | 11 | PERMISSION_DENIED | The DoiT user or the active customer context does not have access. |
| 500 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- list-billing-transfer-end-customers — List end-customers under a reseller PMA
- list-billing-transfer-end-customers-by-reseller — List end-customers under a reseller PMA, by reseller PMA alone
- list-billing-transfer-reseller-accounts — List the caller's reseller PMA nodes
- list-billing-transfer-reseller-accounts-with-tenants — List the caller's reseller PMA nodes with their end-customer tenants
- create-billing-transfer-reseller-handshakes — Create reseller handshakes (batch)
- API reference: POST /billingtransfer/v1/end-customer-mappings
Aliases: createbillingtransferendcustomermappings