Endpoint reference

POST /api/v1/smart-accounts/binding-challenges

Parameters

NameLocationDetails
X-Juicebox-Accountheader / requiredEnrolled account identity, including authority chain and lowercase owner address. Enrollment derives this identity before the account exists.
X-Juicebox-Signerheader / requiredOwner wallet or authorized bot address that signed this request.
X-Juicebox-Issued-Atheader / requiredUnix seconds, sent as 1–13 decimal digits without leading zeros; at most 30 seconds ahead of server time.
X-Juicebox-Expires-Atheader / requiredUnix seconds, sent as 1–13 decimal digits without leading zeros; in the future and within 300 seconds of issuedAt.
X-Juicebox-Nonceheader / requiredFresh random 32-byte lowercase nonce. A consumed nonce cannot be retried.
X-Juicebox-Signatureheader / requiredEIP-712 CenterRequest signature over every signed field. Contract-owner signatures may vary in length. This is a computed request proof, not a reusable API key.
X-Juicebox-Grantheader / optionalAuthorized bot grant ID. Required for a bot; omit for the owner, signing grantId as the empty string.
Idempotency-Keyheader / optionalSigned retry identity. Required on plan creation and transaction submission. Preserve exact method, target, Content-Type, and body bytes; use a fresh request nonce and signature.

Request body

FieldTypeDetails
manifestIdstring
required
addressstring
required
noncevalue
required
expiresAtinteger
required
Future Unix seconds no more than 900 seconds after server time.
JSON schema
{
  "type": "object",
  "properties": {
    "manifestId": {
      "type": "string"
    },
    "address": {
      "$ref": "#/components/schemas/Address"
    },
    "nonce": {
      "allOf": [
        {
          "$ref": "#/components/schemas/Hash"
        },
        {
          "not": {
            "const": "0x0000000000000000000000000000000000000000000000000000000000000000"
          }
        }
      ]
    },
    "expiresAt": {
      "$ref": "#/components/schemas/UnixSeconds",
      "description": "Future Unix seconds no more than 900 seconds after server time."
    }
  },
  "required": [
    "manifestId",
    "address",
    "nonce",
    "expiresAt"
  ],
  "additionalProperties": false,
  "description": "Select a server-published reviewed manifest and an existing Safe distinct from the API owner EOA. The API owner must be a current Safe owner. Nonce must be nonzero."
}

Response 200

FieldTypeDetails
stateobject
required
Fields
FieldTypeDetails
chainIdinteger
required
addressstring
required
manifestIdstring
required
manifestRevisionstring
required
ownersarray
required
Fields

string

thresholdinteger
required
safeNoncestring
required
uint256 as a lossless decimal string
stateHashstring
required
evidenceobject
required
Fields
FieldTypeDetails
chainIdinteger
required

Values: [1,10,8453,42161,84532,421614,11155111,11155420]

blockNumberstring
required
uint256 as a lossless decimal string
blockHashstring
required
timestampstring
required
uint256 as a lossless decimal string
sourcestring
required

Values: ["onchain"]

codeHashesarray
required
Fields
FieldTypeDetails
addressstring
required
runtimeCodeHashstring
required
modulesone of
required
moduleConfigurationVerifiedboolean
required
executionVerifiedboolean
required

Values: [false]

ownerProfileobject
optional
Fields
FieldTypeDetails
versionstring
required

Values: ["center-passkey-v1"]

signerobject
required
devicesarray
optional
recoveryOwnerobject
required
digeststring
required
typedDataobject
required
Fields
FieldTypeDetails
domainobject
required
Fields
FieldTypeDetails
namestring
required

Values: ["Juicebox Center Smart Account"]

versionstring
required

Values: ["1"]

chainIdinteger
required
verifyingContractstring
required
saltstring
required
primaryTypestring
required

Values: ["BindSmartAccount"]

typesobject
required

Values: [{"BindSmartAccount":[{"name":"accountId","type":"string"},{"name":"owner","type":"address"},{"name":"stateHash","type":"bytes32"},{"name":"nonce","type":"bytes32"},{"name":"expiresAt","type":"uint64"}]}]

messageobject
required
Fields
FieldTypeDetails
accountIdstring
required
Authority chain and lowercase owner address; the authority chain is independent of a transaction's destination chain.
ownerstring
required
stateHashstring
required
noncevalue
required
expiresAtstring
required
Uint64 typed-data value serialized as a decimal string. Challenge request expiresAt uses a JSON integer in Unix seconds.
JSON schema
{
  "type": "object",
  "properties": {
    "state": {
      "$ref": "#/components/schemas/SmartAccountState"
    },
    "digest": {
      "$ref": "#/components/schemas/Hash"
    },
    "typedData": {
      "type": "object",
      "properties": {
        "domain": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "const": "Juicebox Center Smart Account"
            },
            "version": {
              "type": "string",
              "const": "1"
            },
            "chainId": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            },
            "verifyingContract": {
              "$ref": "#/components/schemas/Address"
            },
            "salt": {
              "$ref": "#/components/schemas/Hash"
            }
          },
          "required": [
            "name",
            "version",
            "chainId",
            "verifyingContract",
            "salt"
          ],
          "additionalProperties": false
        },
        "primaryType": {
          "type": "string",
          "const": "BindSmartAccount"
        },
        "types": {
          "type": "object",
          "const": {
            "BindSmartAccount": [
              {
                "name": "accountId",
                "type": "string"
              },
              {
                "name": "owner",
                "type": "address"
              },
              {
                "name": "stateHash",
                "type": "bytes32"
              },
              {
                "name": "nonce",
                "type": "bytes32"
              },
              {
                "name": "expiresAt",
                "type": "uint64"
              }
            ]
          }
        },
        "message": {
          "type": "object",
          "properties": {
            "accountId": {
              "$ref": "#/components/schemas/AccountId"
            },
            "owner": {
              "$ref": "#/components/schemas/Address"
            },
            "stateHash": {
              "$ref": "#/components/schemas/Hash"
            },
            "nonce": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Hash"
                },
                {
                  "not": {
                    "const": "0x0000000000000000000000000000000000000000000000000000000000000000"
                  }
                }
              ]
            },
            "expiresAt": {
              "type": "string",
              "pattern": "^(?:0|9007199254740991|[1-9][0-9]{0,14}|[1-8][0-9]{15}|900[0-6][0-9]{12}|90070[0-9]{11}|90071[0-8][0-9]{10}|900719[0-8][0-9]{9}|9007199[0-1][0-9]{8}|90071992[0-4][0-9]{7}|900719925[0-3][0-9]{6}|9007199254[0-6][0-9]{5}|90071992547[0-3][0-9]{4}|9007199254740[0-8][0-9]{2}|90071992547409[0-8][0-9]{1}|9007199254740990[0-9]{0})$",
              "description": "Uint64 typed-data value serialized as a decimal string. Challenge request `expiresAt` uses a JSON integer in Unix seconds."
            }
          },
          "required": [
            "accountId",
            "owner",
            "stateHash",
            "nonce",
            "expiresAt"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "domain",
        "primaryType",
        "types",
        "message"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "state",
    "digest",
    "typedData"
  ],
  "additionalProperties": false
}