Assemble a signed transaction

Insert signatures into an unsigned transaction, verify them, and optionally broadcast.

# Assemble a signed transaction

`POST https://api.rarebl.com/open/tx/assemble`

Inserts your signatures into an unsigned transaction from tx/build, verifies them, and can broadcast the result in the same call.

**Rate class:** compute (2 requests per second, burst 10, per IP). **Available since:** Open API v2.

**Warning.** With broadcast set to true this really broadcasts the transaction to the live network. It cannot be undone.

## Request

Send a JSON body (`Content-Type: application/json`). No API key is needed: `X-API-KEY` is reserved and ignored.

Example: `curl -X POST "https://api.rarebl.com/open/tx/assemble" -H "Content-Type: application/json" -d '{"unsigned":{"chain":"dash","format":"utxo-v1","tx":"0200000001139f6185036ea872d9e52bd7424ba9165f31b6479556b021fe4b8f3f42e8087a0100000000ffffffff0240420f00000000001976a91454072845a9ca039a5b585f5fd994d88d38feb31c88ac189f3419000000001976a9147fb0a45f00c25ff1cb67753221326c7c420b8b2388ac00000000","inputs":[{"txid":"7a08e8423f8f4bfe21b0569547b6315f16a94b42d72be5d972a86e0385619f13","vout":1,"address":"XnL1FvTKqe6aWfB8NrvgbUMuWCEA3dNxfF","value":"4.23879226","valueSats":"423879226","scriptPubKey":"76a9147fb0a45f00c25ff1cb67753221326c7c420b8b2388ac","scriptType":"p2pkh","sequence":4294967295}],"outputs":[{"address":"XiM9Afap6UEb5LDkcWrg2YyA28hifkZZKM","value":"0.01","valueSats":"1000000","change":false},{"address":"XnL1FvTKqe6aWfB8NrvgbUMuWCEA3dNxfF","value":"4.22879","valueSats":"422879000","change":true}],"fee":"0.00000226","feeSats":"226","vsize":226,"feeRate":"1"},"signatures":[{"index":0,"signature":"3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01","publicKey":"03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873"}],"broadcast":false}'`

## Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `unsigned` | object | Yes | The `unsigned` object exactly as returned by tx/build. |
| `signatures` | array | Yes | One entry per digest: `{index, signature, publicKey}`. UTXO: DER plus the sighash byte (ECDSA) or 64/65-byte hex (Schnorr); `publicKey` is the 33-byte compressed key (p2tr: 32-byte x-only). ETH and TRON: 65-byte `r‖s‖v` hex (v = 0/1 or 27/28), `publicKey` optional. |
| `broadcast` | boolean | No | Broadcast the signed transaction. With `true` the call is in the write class and really broadcasts. Default false. One of: false, true. |

## Responses

### API200 (HTTP 200): OK

A signed transaction, not broadcast.

```json
{
  "status": 1,
  "code": "API200",
  "message": "success",
  "data": {
    "signed": {
      "chain": "dash",
      "hex": "0200000001139f6185036ea872d9e52bd7424ba9165f31b6479556b021fe4b8f3f42e8087a010000006a473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873ffffffff0240420f00000000001976a91454072845a9ca039a5b585f5fd994d88d38feb31c88ac189f3419000000001976a9147fb0a45f00c25ff1cb67753221326c7c420b8b2388ac00000000",
      "txid": "8235cfafa0ef70d4a5135331c6889a7c15780b7aeb3bc20721571c2a4b51ffa7"
    },
    "broadcast": null
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `data.signed` | object | `{chain, hex \| tx, txid}`: the signed transaction (UTXO and ETH `hex`, TRON `tx`). |
| `data.broadcast` | object \| null | null unless `broadcast: true`; then `{txid, accepted, alreadyKnown}`. |

### API200 (HTTP 200): OK (broadcast)

With `broadcast: true`.

```json
{
  "status": 1,
  "code": "API200",
  "message": "success",
  "data": {
    "signed": {
      "chain": "dash",
      "hex": "0200000001139f6185036ea872d9e52bd7424ba9165f31b6479556b021fe4b8f3f42e8087a010000006a473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873ffffffff0240420f00000000001976a91454072845a9ca039a5b585f5fd994d88d38feb31c88ac189f3419000000001976a9147fb0a45f00c25ff1cb67753221326c7c420b8b2388ac00000000",
      "txid": "8235cfafa0ef70d4a5135331c6889a7c15780b7aeb3bc20721571c2a4b51ffa7"
    },
    "broadcast": {
      "txid": "8235cfafa0ef70d4a5135331c6889a7c15780b7aeb3bc20721571c2a4b51ffa7",
      "accepted": true,
      "alreadyKnown": false
    }
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API422 (HTTP 422): Unprocessable Entity

We verify every signature against its digest and public key.

```json
{
  "status": 0,
  "code": "API422",
  "message": "A signature does not verify against its digest.",
  "data": {
    "reason": "bad_signature"
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API403 (HTTP 403): Forbidden

The key must derive the address of the input it signs.

```json
{
  "status": 0,
  "code": "API403",
  "message": "The public key does not match the input address.",
  "data": {
    "reason": "key_mismatch"
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API422 (HTTP 422): Unprocessable Entity

Only with `broadcast: true`: the node refused it. `data.detail` carries the node message.

```json
{
  "status": 0,
  "code": "API422",
  "message": "The node rejected the transaction.",
  "data": {
    "reason": "node_rejected",
    "detail": "min relay fee not met"
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API400 (HTTP 400): Bad Request

A parameter is missing or malformed. `data.param` names it (here `unsigned`).

```json
{
  "status": 0,
  "code": "API400",
  "message": "unsigned is required.",
  "data": {
    "param": "unsigned"
  },
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API429 (HTTP 429): Too Many Requests

Rate limited (compute class: 2 requests per second, burst 10, per IP). A `Retry-After` header says how long to wait, in seconds.

```json
{
  "status": 0,
  "code": "API429",
  "message": "Too many requests. Please retry shortly.",
  "data": null,
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

### API502 (HTTP 502): Bad Gateway

The node is unavailable, still syncing or timed out. Retry later with a short back-off.

```json
{
  "status": 0,
  "code": "API502",
  "message": "The node is unavailable or timed out. Please try again.",
  "data": null,
  "go": null,
  "meta": {
    "requestid": "0123456789abcdef",
    "notices": []
  }
}
```

## Notes

- We check every signature against its digest and key, and that the key matches the input address (`bad_signature`, `key_mismatch`).
- Assemble without `broadcast` is in the compute class. With `broadcast: true` it is in the write class (6 per minute, burst 3, 300 per day).
- The SDK does build, verify, sign, assemble and broadcast in one `transfer()` call: see [Sign locally with the SDK](https://docs.rarebl.com/guides/sign-locally).

Back to the Rarebl AI documentation index