Skip to content

Issue an API key

POST
/v1/api-keys
curl --request POST \
--url https://api.pealboard.com/v1/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "name": "Deploy script", "scopes": [], "expiresAt": "2026-04-15T12:00:00Z" }'

The key is in this response and is never shown again. Copy it now; Pealboard keeps only a digest of it.

The key acts with the role of the member who issued it, narrowed by scopes. An empty scopes is not narrowed and may do anything that member may do. keys:read and keys:write cannot be granted: a credential that can mint credentials makes revoking a leaked one a matter of enumerating its descendants rather than deleting a row.

Only a signed-in person may issue one, for the same reason.

Idempotency-Key is accepted and deliberately not honoured here: recording the answer would keep the key itself in storage for a day, which is the one thing this route promises not to do. A retry issues a second key; revoke whichever you did not keep.

Access. Requires the admin role or above (admin, owner). Issuing a credential that acts for the workspace is an administrative act. API-key scope: keys:write.

Media typeapplication/json
object
name
required

What it is for. Shown in the list and in the audit log.

string
>= 1 characters <= 80 characters
Example
Deploy script
scopes

What the key may do. Empty means anything the member who issued it may do.

Array<string>
default:
Allowed values: workspace:read workspace:write members:read members:write github:read github:write issues:read issues:write projects:read projects:write portals:read portals:write requests:read requests:write views:read views:write
expiresAt

When it stops working. Omit for a key that does not expire.

string format: date-time

The key, once.

Media typeapplication/json
object
id
required

A UUID this API issued.

string format: uuid
name
required
string
prefix
required

Every Pealboard key begins with this.

string
last4
required

The last four characters, to tell two keys apart.

string
scopes
required

Empty means the key may do anything the membership that issued it may do.

Array<string>
Allowed values: self:read workspace:read workspace:write members:read members:write github:read github:write issues:read issues:write projects:read projects:write portals:read portals:write requests:read requests:write views:read views:write keys:read keys:write
createdByMembershipId
required

A UUID this API issued.

string format: uuid
expiresAt
required
string | null format: date-time
lastUsedAt
required

Recorded at most once a minute, so a busy key does not write a row per request.

string | null format: date-time
createdAt
required
string format: date-time
key
required

The key itself. This is the only time it is returned; Pealboard stores a SHA-256 digest.

string
Example
{
"prefix": "pb_",
"scopes": [
"self:read"
],
"key": "pb_AbCdEf0123456789AbCdEf0123456789AbCdEf01"
}

No valid credentials.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

Authenticated, but not permitted.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

No such resource, or it is not visible to you.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

The request conflicts with the current state.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

The request did not match the expected shape.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

Rate limited. Retry after the interval in the header.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}

GitHub or another dependency refused or did not answer. Nothing in the workspace changed.

Media typeapplication/json
object
error
required
object
code
required

A stable identifier for the kind of failure. Safe to branch on.

string
message
required

What went wrong, written for a person.

string
detail

Structured particulars, when there are any.

object
key
additional properties
remedy

What to do about it, when there is something to do.

string
requestId
required

Quote this when asking about a specific failure.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": {
"additionalProperty": "example"
},
"remedy": "example",
"requestId": "example"
}
}