Parchment Docs

Users

User and profile management

Get Auth Sessions Current

GET
/auth/sessions/current

Response Body

curl -X GET "https://example.com/auth/sessions/current"
fetch("https://example.com/auth/sessions/current")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/auth/sessions/current"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/auth/sessions/current"

response = requests.request("GET", url)

print(response.text)
Empty

Get Users

GET
/users

Response Body

curl -X GET "https://example.com/users/"
fetch("https://example.com/users/")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/"

response = requests.request("GET", url)

print(response.text)
Empty

Create a new user

POST
/users

Request Body

application/jsonRequired
firstNameRequiredstring
lastNameRequiredstring
emailRequiredstring
Format: "email"
picturestring
rolestring

Response Body

curl -X POST "https://example.com/users/" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "picture": "string",
    "role": "user"
  }'
const body = JSON.stringify({
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "picture": "string",
  "role": "user"
})

fetch("https://example.com/users/", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/"
  body := strings.NewReader(`{
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "picture": "string",
    "role": "user"
  }`)
  req, _ := http.NewRequest("POST", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/"
body = {
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "picture": "string",
  "role": "user"
}
response = requests.request("POST", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Get Users Roles

GET
/users/roles

Response Body

curl -X GET "https://example.com/users/roles"
fetch("https://example.com/users/roles")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/roles"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/roles"

response = requests.request("GET", url)

print(response.text)
Empty

Get all permissions

GET
/users/permissions

Response Body

curl -X GET "https://example.com/users/permissions"
fetch("https://example.com/users/permissions")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/permissions"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/permissions"

response = requests.request("GET", url)

print(response.text)
Empty

Post Users Me Identity Reset

Last-resort: wipe all of this user's encrypted data and clear the federation identity so they can re-run identity setup. Session + passkeys survive; everything encrypted under the old seed is gone. Irreversible.

POST
/users/me/identity/reset

Request Body

application/jsonRequired
confirmRequiredstring

Response Body

curl -X POST "https://example.com/users/me/identity/reset" \
  -H "Content-Type: application/json" \
  -d '{
    "confirm": "erase-all-my-data"
  }'
const body = JSON.stringify({
  "confirm": "erase-all-my-data"
})

fetch("https://example.com/users/me/identity/reset", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/identity/reset"
  body := strings.NewReader(`{
    "confirm": "erase-all-my-data"
  }`)
  req, _ := http.NewRequest("POST", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/identity/reset"
body = {
  "confirm": "erase-all-my-data"
}
response = requests.request("POST", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Get Users Me Revocations Pending

List peer handles queued for revocation after an identity reset.

GET
/users/me/revocations/pending

Response Body

curl -X GET "https://example.com/users/me/revocations/pending"
fetch("https://example.com/users/me/revocations/pending")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/revocations/pending"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/revocations/pending"

response = requests.request("GET", url)

print(response.text)
Empty

Post Users Me Revocations Flush

Deliver client-signed RELATIONSHIP_REVOKE envelopes to their peers. Rows that deliver are dropped; failures stay queued for retry.

POST
/users/me/revocations/flush

Request Body

application/jsonRequired
itemsRequiredarray<object>

Response Body

curl -X POST "https://example.com/users/me/revocations/flush" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "peerHandle": "string",
        "signature": "string",
        "nonce": "string",
        "timestamp": "string",
        "messageVersion": 0
      }
    ]
  }'
const body = JSON.stringify({
  "items": [
    {
      "peerHandle": "string",
      "signature": "string",
      "nonce": "string",
      "timestamp": "string",
      "messageVersion": 0
    }
  ]
})

fetch("https://example.com/users/me/revocations/flush", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/revocations/flush"
  body := strings.NewReader(`{
    "items": [
      {
        "peerHandle": "string",
        "signature": "string",
        "nonce": "string",
        "timestamp": "string",
        "messageVersion": 0
      }
    ]
  }`)
  req, _ := http.NewRequest("POST", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/revocations/flush"
body = {
  "items": [
    {
      "peerHandle": "string",
      "signature": "string",
      "nonce": "string",
      "timestamp": "string",
      "messageVersion": 0
    }
  ]
}
response = requests.request("POST", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Delete Users Me Revocations Pending By Peer Handle

Drop a queued revocation without delivering it.

DELETE
/users/me/revocations/pending/{peerHandle}

Path Parameters

peerHandleRequiredstring

Response Body

curl -X DELETE "https://example.com/users/me/revocations/pending/string"
fetch("https://example.com/users/me/revocations/pending/string")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/revocations/pending/string"

  req, _ := http.NewRequest("DELETE", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/revocations/pending/string"

response = requests.request("DELETE", url)

print(response.text)
Empty

Get Users Me Identity

Get current user federation identity (handle, keys)

GET
/users/me/identity

Response Body

curl -X GET "https://example.com/users/me/identity"
fetch("https://example.com/users/me/identity")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/identity"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/identity"

response = requests.request("GET", url)

print(response.text)
Empty

Patch Users Me Alias

Update current user alias (username for federation)

PATCH
/users/me/alias

Request Body

application/jsonRequired
aliasRequiredstring

Response Body

curl -X PATCH "https://example.com/users/me/alias" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "string"
  }'
const body = JSON.stringify({
  "alias": "string"
})

fetch("https://example.com/users/me/alias", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/alias"
  body := strings.NewReader(`{
    "alias": "string"
  }`)
  req, _ := http.NewRequest("PATCH", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/alias"
body = {
  "alias": "string"
}
response = requests.request("PATCH", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Put Users Me Keys

Register or update federation public keys

PUT
/users/me/keys

Request Body

application/jsonRequired
signingKeyRequiredstring
encryptionKeyRequiredstring

Response Body

curl -X PUT "https://example.com/users/me/keys" \
  -H "Content-Type: application/json" \
  -d '{
    "signingKey": "string",
    "encryptionKey": "string"
  }'
const body = JSON.stringify({
  "signingKey": "string",
  "encryptionKey": "string"
})

fetch("https://example.com/users/me/keys", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/keys"
  body := strings.NewReader(`{
    "signingKey": "string",
    "encryptionKey": "string"
  }`)
  req, _ := http.NewRequest("PUT", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/keys"
body = {
  "signingKey": "string",
  "encryptionKey": "string"
}
response = requests.request("PUT", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Patch Users Me Profile

Update current user display profile (first/last name)

PATCH
/users/me/profile

Request Body

application/jsonRequired
firstNamestring | null | null
lastNamestring | null | null

Response Body

curl -X PATCH "https://example.com/users/me/profile" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "string",
    "lastName": "string"
  }'
const body = JSON.stringify({
  "firstName": "string",
  "lastName": "string"
})

fetch("https://example.com/users/me/profile", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/profile"
  body := strings.NewReader(`{
    "firstName": "string",
    "lastName": "string"
  }`)
  req, _ := http.NewRequest("PATCH", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/profile"
body = {
  "firstName": "string",
  "lastName": "string"
}
response = requests.request("PATCH", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Get Users Me Km version

Get current master-key version (Part C.7)

GET
/users/me/km-version

Response Body

curl -X GET "https://example.com/users/me/km-version"
fetch("https://example.com/users/me/km-version")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/km-version"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/km-version"

response = requests.request("GET", url)

print(response.text)
Empty

Post Users Me Km version Commit

Atomic rotation commit. Applies new public keys, re-encrypted blobs, re-encrypted collection envelopes, and re-sealed slots in a single transaction gated by a CAS on kmVersion. 409 on conflict — nothing is written.

POST
/users/me/km-version/commit

Request Body

application/jsonRequired
expectedCurrentRequirednumber
signingKeyRequiredstring
encryptionKeyRequiredstring
blobsarray<object>
collectionsarray<object>
slotsarray<object>

Response Body

curl -X POST "https://example.com/users/me/km-version/commit" \
  -H "Content-Type: application/json" \
  -d '{
    "expectedCurrent": 0,
    "signingKey": "string",
    "encryptionKey": "string",
    "blobs": [
      {
        "blobType": "string",
        "encryptedBlob": "string"
      }
    ],
    "collections": [
      {
        "id": "string",
        "metadataEncrypted": "string"
      }
    ],
    "slots": [
      {
        "credentialId": "string",
        "wrappedKm": "string",
        "wrapAlgo": "string",
        "slotSignature": "string"
      }
    ]
  }'
const body = JSON.stringify({
  "expectedCurrent": 0,
  "signingKey": "string",
  "encryptionKey": "string",
  "blobs": [
    {
      "blobType": "string",
      "encryptedBlob": "string"
    }
  ],
  "collections": [
    {
      "id": "string",
      "metadataEncrypted": "string"
    }
  ],
  "slots": [
    {
      "credentialId": "string",
      "wrappedKm": "string",
      "wrapAlgo": "string",
      "slotSignature": "string"
    }
  ]
})

fetch("https://example.com/users/me/km-version/commit", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/km-version/commit"
  body := strings.NewReader(`{
    "expectedCurrent": 0,
    "signingKey": "string",
    "encryptionKey": "string",
    "blobs": [
      {
        "blobType": "string",
        "encryptedBlob": "string"
      }
    ],
    "collections": [
      {
        "id": "string",
        "metadataEncrypted": "string"
      }
    ],
    "slots": [
      {
        "credentialId": "string",
        "wrappedKm": "string",
        "wrapAlgo": "string",
        "slotSignature": "string"
      }
    ]
  }`)
  req, _ := http.NewRequest("POST", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/km-version/commit"
body = {
  "expectedCurrent": 0,
  "signingKey": "string",
  "encryptionKey": "string",
  "blobs": [
    {
      "blobType": "string",
      "encryptedBlob": "string"
    }
  ],
  "collections": [
    {
      "id": "string",
      "metadataEncrypted": "string"
    }
  ],
  "slots": [
    {
      "credentialId": "string",
      "wrappedKm": "string",
      "wrapAlgo": "string",
      "slotSignature": "string"
    }
  ]
}
response = requests.request("POST", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Get Users Me Preferences

Get current user preferences (language, unit system)

GET
/users/me/preferences

Response Body

curl -X GET "https://example.com/users/me/preferences"
fetch("https://example.com/users/me/preferences")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/preferences"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/preferences"

response = requests.request("GET", url)

print(response.text)
Empty

Put Users Me Preferences

Update current user preferences (language, unit system)

PUT
/users/me/preferences

Request Body

application/jsonRequired
languagestring
unitSystemstring

Response Body

curl -X PUT "https://example.com/users/me/preferences" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "string",
    "unitSystem": "metric"
  }'
const body = JSON.stringify({
  "language": "string",
  "unitSystem": "metric"
})

fetch("https://example.com/users/me/preferences", {
  body
})
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
  "strings"
)

func main() {
  url := "https://example.com/users/me/preferences"
  body := strings.NewReader(`{
    "language": "string",
    "unitSystem": "metric"
  }`)
  req, _ := http.NewRequest("PUT", url, body)
  req.Header.Add("Content-Type", "application/json")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/preferences"
body = {
  "language": "string",
  "unitSystem": "metric"
}
response = requests.request("PUT", url, json = body, headers = {
  "Content-Type": "application/json"
})

print(response.text)
Empty

Get (or lazily create) the per-device wrap secret used by the client to derive the localStorage-seed wrap key. Idempotent.

GET
/users/me/devices/{deviceId}/wrap-secret

Path Parameters

deviceIdRequiredstring
Minimum length: 8Maximum length: 64Pattern: "^[a-zA-Z0-9-]+$"

Response Body

curl -X GET "https://example.com/users/me/devices/stringst/wrap-secret"
fetch("https://example.com/users/me/devices/stringst/wrap-secret")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/devices/stringst/wrap-secret"

  req, _ := http.NewRequest("GET", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/devices/stringst/wrap-secret"

response = requests.request("GET", url)

print(response.text)
Empty
curl -X POST "https://example.com/users/me/device-wrap-secrets/rotate"
fetch("https://example.com/users/me/device-wrap-secrets/rotate")
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://example.com/users/me/device-wrap-secrets/rotate"

  req, _ := http.NewRequest("POST", url, nil)
  
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import requests

url = "https://example.com/users/me/device-wrap-secrets/rotate"

response = requests.request("POST", url)

print(response.text)
Empty