create-billing-transfer-reseller-handshakes
dci create-billing-transfer-reseller-handshakes [body] [flags]
Maps reseller to distributor; also sends the handshake if required, as part of AWS
billing transfer onboarding. Distributor-only; callers without the ChannelOps distributor
tier entitlement receive 403.
Each item in the batch is processed independently; per-item outcomes are returned in
results[] with HTTP 200 even when some items fail. Malformed items (missing fields,
duplicate resellerPmaAccountId within the batch) are rejected up front with 422 and
reported in invalidItems, and none of the batch is processed in that case.
Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.
--dry-run is the API's simulation hereFor this command --dry-run is forwarded to the API, which validates the batch and
returns the full results/summary shape without issuing any AWS Organizations
handshakes (handshakeId is absent). This differs from the CLI's local --dry-run
preview on delete-* commands, which never contacts the API.
sendHandshakes defaults to false: without it the batch is mapped in place and no
handshake is issued. Duplicate resellerPmaAccountId values within one batch are
rejected with 422 before anything is processed. --idempotency-key accepts up to 255
characters; a UUID v4 or ULID is recommended.
Examples
# Map reseller PMAs to your distributor PMA in place, without issuing AWS Organizations handshakes (distributor tenants only).
dci create-billing-transfer-reseller-handshakes < mapping.json
# mapping.json
{"dpmaId": "<dpma-id>",
"items": [{"resellerCustomerId": "<customer-id>", "resellerPmaAccountId": "123456789012"}]}
# Simulate a batch that would issue handshakes; the response has the same shape as a real run but nothing is sent to AWS.
dci create-billing-transfer-reseller-handshakes --dry-run < handshakes.json
# handshakes.json
{"dpmaId": "<dpma-id>", "sendHandshakes": true,
"items": [
{"resellerCustomerId": "<customer-id>", "resellerPmaAccountId": "123456789012"},
{"resellerCustomerId": "<customer-id>", "resellerPmaAccountId": "210987654321"}]}
# Issue the handshakes for real, with an idempotency key so a retry returns the cached result instead of re-sending.
dci create-billing-transfer-reseller-handshakes --idempotency-key <idempotency-key> < handshakes.json
`results[]` carries one entry per item with its `status` (`handshake_issued`, `no_op`, `mapped`, `remapped` or `failed`) and `summary` totals them.
# Per-item outcomes as JSON, for scripts.
dci create-billing-transfer-reseller-handshakes --idempotency-key <idempotency-key> --output json < handshakes.json
Request
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
dpmaId | string | yes | The distributor's program management account (DPMA) ID issuing the handshakes. |
sendHandshakes | boolean | If true, issues a new AWS Organizations handshake for each item without an existing one. If omitted or false, maps the batch in place without issuing any AWS Organizations handshakes. Default: false. | |
items | array of object | yes | Batch items. Duplicate resellerPmaAccountId values within the batch are rejected. |
items[].resellerCustomerId | string | yes | DoiT customer ID of the reseller's end customer to issue a handshake for. |
items[].resellerPmaAccountId | string | yes | 12-digit AWS account ID of the reseller's program management account (PMA). |
Raw JSON schema
{
"type": "object",
"additionalProperties": false,
"required": [
"dpmaId",
"items"
],
"properties": {
"dpmaId": {
"type": "string",
"description": "The distributor's program management account (DPMA) ID issuing the handshakes."
},
"sendHandshakes": {
"type": "boolean",
"description": "If `true`, issues a new AWS Organizations handshake for each item without an existing one. If omitted or `false`, maps the batch in place without issuing any AWS Organizations handshakes.",
"default": false
},
"items": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"description": "Batch items. Duplicate `resellerPmaAccountId` values within the batch are rejected.",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"resellerCustomerId",
"resellerPmaAccountId"
],
"properties": {
"resellerCustomerId": {
"type": "string",
"description": "DoiT customer ID of the reseller's end customer to issue a handshake for."
},
"resellerPmaAccountId": {
"type": "string",
"description": "12-digit AWS account ID of the reseller's program management account (PMA).",
"example": "123456789012"
}
}
}
}
}
}
Flags
| Flag | Type | Default | Example | Description |
|---|---|---|---|---|
--dry-run | boolean | false | If true, validates the batch and simulates the outcome without issuing any AWS Organizations handshakes. The response shape is identical to a real execution. |
Every command also accepts the CLI-wide flags for output shaping — see Output formats and Table output options.
Output
OK - Batch processed; see results and summary for per-item outcomes.
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 | |
results | array of object | |
results[].resellerCustomerId | string | |
results[].resellerPmaAccountId | string | |
results[].status | string | Outcome of processing this batch item. One of: "handshake_issued", "no_op", "mapped", "remapped", "failed". |
results[].handshakeId | string | AWS Organizations handshake ID. Absent when no handshake was issued (e.g. no_op, failed, or dry run). |
results[].handshakeState | string | AWS Organizations Handshake State value, lowercased. One of: "requested", "open", "canceled", "accepted", "declined", "expired". |
results[].error | object | |
results[].error.code | string | Stable machine-readable error code for this item. |
results[].error.message | string | Human-readable explanation of the failure. |
summary | object | Per-outcome counts across the batch. Field names are snake_case, matching the actual wire format returned by this endpoint — an intentional inconsistency with the rest of the payload, which is camelCase. |
summary.handshake_issued | integer | |
summary.no_op | integer | |
summary.mapped | integer | |
summary.remapped | integer | |
summary.failed | integer |
Raw JSON schema
{
"type": "object",
"additionalProperties": false,
"required": [
"dpmaId",
"results",
"summary"
],
"properties": {
"dpmaId": {
"type": "string"
},
"results": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"resellerCustomerId",
"resellerPmaAccountId",
"status"
],
"properties": {
"resellerCustomerId": {
"type": "string"
},
"resellerPmaAccountId": {
"type": "string"
},
"status": {
"type": "string",
"description": "Outcome of processing this batch item.",
"enum": [
"handshake_issued",
"no_op",
"mapped",
"remapped",
"failed"
]
},
"handshakeId": {
"type": "string",
"description": "AWS Organizations handshake ID. Absent when no handshake was issued (e.g. `no_op`, `failed`, or dry run)."
},
"handshakeState": {
"type": "string",
"description": "AWS Organizations Handshake `State` value, lowercased.",
"enum": [
"requested",
"open",
"canceled",
"accepted",
"declined",
"expired"
]
},
"error": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"description": "Stable machine-readable error code for this item."
},
"message": {
"type": "string",
"description": "Human-readable explanation of the failure."
}
}
}
}
}
},
"summary": {
"type": "object",
"description": "Per-outcome counts across the batch. Field names are snake_case, matching the actual wire format returned by this endpoint — an intentional inconsistency with the rest of the payload, which is camelCase.",
"additionalProperties": false,
"required": [
"handshake_issued",
"no_op",
"mapped",
"remapped",
"failed"
],
"properties": {
"handshake_issued": {
"type": "integer"
},
"no_op": {
"type": "integer"
},
"mapped": {
"type": "integer"
},
"remapped": {
"type": "integer"
},
"failed": {
"type": "integer"
}
}
}
}
}
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, 502 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- list-billing-transfer-program-management-accounts — List program management accounts
- get-billing-transfer-program-management-accounts-status — Get program management account status
- create-billing-transfer-end-customer-mappings — Create end-customer mappings (batch)
- list-billing-transfer-end-customers — List end-customers under a reseller PMA
- API reference: POST /billingtransfer/v1/resellerhandshakes
Aliases: createbillingtransferresellerhandshakes