curl --request POST \
--url https://api.platform.dakota.xyz/signers \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}
'const options = {
method: 'POST',
headers: {
'x-idempotency-key': '<x-idempotency-key>',
'x-api-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: 'Marc', public_key: 'string', key_type: 'ES256'})
};
fetch('https://api.platform.dakota.xyz/signers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.platform.dakota.xyz/signers"
payload = {
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}
headers = {
"x-idempotency-key": "<x-idempotency-key>",
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.platform.dakota.xyz/signers"
payload := strings.NewReader("{\n \"name\": \"Marc\",\n \"public_key\": \"string\",\n \"key_type\": \"ES256\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-idempotency-key", "<x-idempotency-key>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"client_id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#invalid-request",
"title": "Bad request - invalid input data",
"status": 400,
"detail": "Bad request - invalid input data",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#authentication-error",
"title": "Unauthorized",
"status": 401,
"detail": "Unauthorized",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Forbidden",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#conflict",
"title": "Conflict - duplicate request detected",
"status": 409,
"detail": "Conflict - duplicate request detected",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#internal-error",
"title": "Internal server error",
"status": 500,
"detail": "Internal server error",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}Create a new signer
Creates a signer resource that can be attached to signer groups.
A public key belongs to exactly one organization. A key already registered by another organization returns 409, and that response carries no detail about the existing signer — including when the key backs that organization’s platform-managed settlement signer, which returns the same 409 rather than a distinguishable refusal. 403 is reserved for your own platform-managed key material, which you may not re-register.
curl --request POST \
--url https://api.platform.dakota.xyz/signers \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}
'const options = {
method: 'POST',
headers: {
'x-idempotency-key': '<x-idempotency-key>',
'x-api-key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: 'Marc', public_key: 'string', key_type: 'ES256'})
};
fetch('https://api.platform.dakota.xyz/signers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.platform.dakota.xyz/signers"
payload = {
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}
headers = {
"x-idempotency-key": "<x-idempotency-key>",
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.platform.dakota.xyz/signers"
payload := strings.NewReader("{\n \"name\": \"Marc\",\n \"public_key\": \"string\",\n \"key_type\": \"ES256\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-idempotency-key", "<x-idempotency-key>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"client_id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Marc",
"public_key": "string",
"key_type": "ES256"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#invalid-request",
"title": "Bad request - invalid input data",
"status": 400,
"detail": "Bad request - invalid input data",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#authentication-error",
"title": "Unauthorized",
"status": 401,
"detail": "Unauthorized",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Forbidden",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#conflict",
"title": "Conflict - duplicate request detected",
"status": 409,
"detail": "Conflict - duplicate request detected",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#internal-error",
"title": "Internal server error",
"status": 500,
"detail": "Internal server error",
"instance": "https://api.platform.dakota.xyz/signers",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}Authorizations
Headers
Unique key (UUID) to ensure request idempotency on POST, PUT and PATCH requests.
A key is scoped to your client, the HTTP method and the path, and is remembered for 24 hours after a
successful (below 400) response. Repeating the same request (same JSON body, whatever the key order or
whitespace) with the same key within that window returns the original response with
X-Idempotent-Replayed: true instead of executing the request again. Using the same key on the same
endpoint with a different body returns 422 with problem type idempotency-key-reused; the request is
not executed. Error responses (4xx and 5xx) are not remembered, so a request refused for a fixable reason
can be corrected and retried under the same key. Request bodies that are not JSON (for example file
uploads) are not compared.
Body
Request to create a new signer
The signer name
"Marc"
The signer public key. For KEY_TYPE_ES256 this must be a base64-encoded X.509 SubjectPublicKeyInfo (PKIX) for an ECDSA P-256 key. Both PEM-wrapped (with BEGIN/END PUBLIC KEY headers) and raw DER encodings are accepted.
For KEY_TYPE_WEBAUTHN this must be a base64-encoded COSE public key. Only ES256 (EC2 / P-256, COSE alg -7) and RS256 (RSA, 2048-bit minimum, COSE alg -257) keys are supported; other algorithms and curves are rejected. See the WebAuthn & Passkey Signing guide for how each signatures[] entry is then built.
Type of the key
ES256, WEBAUTHN Response
Signer already registered to you. The submitted public key already belongs to one of your existing signers, so no new signer was created. The response carries that signer's persisted id, public_key and key_type (use the returned key_type to sign — it is authoritative and may differ from the one submitted); name echoes the request. Registration is idempotent: re-running setup returns a usable id instead of an error. A public key held by a different client returns 409 and no details about that signer.
A signer is a public key that can sign intents and it is part of a signer group
KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
The signer name
"Marc"
The signer public key. For KEY_TYPE_ES256 this must be a base64-encoded X.509 SubjectPublicKeyInfo (PKIX) for an ECDSA P-256 key. Both PEM-wrapped (with BEGIN/END PUBLIC KEY headers) and raw DER encodings are accepted.
For KEY_TYPE_WEBAUTHN this must be a base64-encoded COSE public key. Only ES256 (EC2 / P-256, COSE alg -7) and RS256 (RSA, 2048-bit minimum, COSE alg -257) keys are supported; other algorithms and curves are rejected. See the WebAuthn & Passkey Signing guide for how each signatures[] entry is then built.
Type of the key
ES256, WEBAUTHN KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Epoch seconds at which this signer was removed from the containing
signer group. Present only for entries in a group's removed_members
(i.e. when include_removed=true); absent for active members.
Was this page helpful?

