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#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#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 to ensure request idempotency. If the same key is used within a certain time window, the original response will be returned instead of executing the request again.
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?

