Retrieve a paginated list of API keys owned by the authenticated portal session’s end user.
This is the portal-scoped variant of apis.listKeys. It authenticates only
with a portal session cookie and always restricts results to the keys owned
by the session’s external identity, within the keyspaces configured on the
portal configuration. Both the identity and the keyspaces come from the
session, so the request body has no externalId or apiId field.
from unkey.py import Unkey, models
with Unkey() as unkey:
res = unkey.portal.list_keys(security=models.PortalListKeysSecurity(
portal_session="<YOUR_API_KEY_HERE>",
), limit=100, cursor="key_1234abcd")
while res is not None:
# Handle items
res = res.next()import { Unkey } from "@unkey/api";
const unkey = new Unkey();
async function run() {
const result = await unkey.portal.listKeys({
portalSession: process.env["UNKEY_PORTAL_SESSION"] ?? "",
}, {
cursor: "key_1234abcd",
});
for await (const page of result) {
console.log(page);
}
}
run();package main
import(
"context"
unkey "github.com/unkeyed/sdks/api/go/v2"
"github.com/unkeyed/sdks/api/go/v2/models/components"
"os"
"github.com/unkeyed/sdks/api/go/v2/models/operations"
"log"
)
func main() {
ctx := context.Background()
s := unkey.New()
res, err := s.Portal.ListKeys(ctx, components.V2PortalListKeysRequestBody{
Cursor: unkey.Pointer("key_1234abcd"),
}, operations.PortalListKeysSecurity{
PortalSession: os.Getenv("UNKEY_PORTAL_SESSION"),
})
if err != nil {
log.Fatal(err)
}
if res.V2PortalListKeysResponseBody != nil {
for {
// handle items
res, err = res.Next()
if err != nil {
// handle error
}
if res == nil {
break
}
}
}
}curl --request POST \
--url https://api.unkey.com/v2/portal.listKeys \
--header 'Content-Type: application/json' \
--cookie portal_session= \
--data '
{
"limit": 100,
"cursor": "key_1234abcd"
}
'const options = {
method: 'POST',
headers: {cookie: 'portal_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({limit: 100, cursor: 'key_1234abcd'})
};
fetch('https://api.unkey.com/v2/portal.listKeys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.unkey.com/v2/portal.listKeys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'limit' => 100,
'cursor' => 'key_1234abcd'
]),
CURLOPT_COOKIE => "portal_session=",
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.post("https://api.unkey.com/v2/portal.listKeys")
.header("cookie", "portal_session=")
.header("Content-Type", "application/json")
.body("{\n \"limit\": 100,\n \"cursor\": \"key_1234abcd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.unkey.com/v2/portal.listKeys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["cookie"] = 'portal_session='
request["Content-Type"] = 'application/json'
request.body = "{\n \"limit\": 100,\n \"cursor\": \"key_1234abcd\"\n}"
response = http.request(request)
puts response.read_body{
"meta": {
"requestId": "req_123"
},
"data": [
{
"keyId": "key_1234567890abcdef",
"start": "sk_test_abc123",
"enabled": true,
"createdAt": 1701425400000,
"name": "Production API Key",
"meta": null,
"updatedAt": 1701425400000,
"lastUsedAt": 1701425400000,
"expires": 1735689600000,
"permissions": [
"documents.read",
"documents.write"
],
"roles": [
"editor",
"viewer"
],
"credits": {
"remaining": 1000,
"refill": {
"interval": "daily",
"amount": 1000,
"refillDay": 15
}
},
"identity": {
"id": "<string>",
"externalId": "<string>",
"meta": {},
"ratelimits": [
{
"id": "rl_1234567890abcdef",
"name": "api_requests",
"limit": 1000,
"duration": 3600000,
"autoApply": true
}
]
},
"plaintext": "sk_test_abc123def456",
"ratelimits": [
{
"id": "rl_1234567890abcdef",
"name": "api_requests",
"limit": 1000,
"duration": 3600000,
"autoApply": true
}
]
}
],
"pagination": {
"hasMore": true,
"cursor": "eyJrZXkiOiJrZXlfMTIzNCIsInRzIjoxNjk5Mzc4ODAwfQ=="
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found",
"errors": [
{
"location": "body.permissions[0].name",
"message": "Must be at least 3 characters long",
"fix": "Ensure the name uses only alphanumeric characters, underscores, and hyphens"
}
]
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}Authorizations
Browser session cookie for the Customer Portal. Set by portal.exchangeSession
and sent automatically by the browser on portal.* requests. Portal sessions
are scoped to a single end user (external identity) and can only access the
portal.* routes.
Body
Maximum number of keys to return per request. Balance between response size and number of pagination calls needed.
1 <= x <= 100Pagination cursor from a previous response to fetch the next page.
Use when hasMore: true in the previous response.
"key_1234abcd"
Response
Successfully retrieved paginated keys. Use the pagination cursor for additional results when hasMore: true.
Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The requestId is particularly important when troubleshooting issues with the Unkey support team.
Show child attributes
Show child attributes
Array of the portal end user's API keys.
100Show child attributes
Show child attributes
Pagination metadata for list endpoints. Provides information necessary to traverse through large result sets efficiently using cursor-based pagination.
Show child attributes
Show child attributes
Was this page helpful?
from unkey.py import Unkey, models
with Unkey() as unkey:
res = unkey.portal.list_keys(security=models.PortalListKeysSecurity(
portal_session="<YOUR_API_KEY_HERE>",
), limit=100, cursor="key_1234abcd")
while res is not None:
# Handle items
res = res.next()import { Unkey } from "@unkey/api";
const unkey = new Unkey();
async function run() {
const result = await unkey.portal.listKeys({
portalSession: process.env["UNKEY_PORTAL_SESSION"] ?? "",
}, {
cursor: "key_1234abcd",
});
for await (const page of result) {
console.log(page);
}
}
run();package main
import(
"context"
unkey "github.com/unkeyed/sdks/api/go/v2"
"github.com/unkeyed/sdks/api/go/v2/models/components"
"os"
"github.com/unkeyed/sdks/api/go/v2/models/operations"
"log"
)
func main() {
ctx := context.Background()
s := unkey.New()
res, err := s.Portal.ListKeys(ctx, components.V2PortalListKeysRequestBody{
Cursor: unkey.Pointer("key_1234abcd"),
}, operations.PortalListKeysSecurity{
PortalSession: os.Getenv("UNKEY_PORTAL_SESSION"),
})
if err != nil {
log.Fatal(err)
}
if res.V2PortalListKeysResponseBody != nil {
for {
// handle items
res, err = res.Next()
if err != nil {
// handle error
}
if res == nil {
break
}
}
}
}curl --request POST \
--url https://api.unkey.com/v2/portal.listKeys \
--header 'Content-Type: application/json' \
--cookie portal_session= \
--data '
{
"limit": 100,
"cursor": "key_1234abcd"
}
'const options = {
method: 'POST',
headers: {cookie: 'portal_session=', 'Content-Type': 'application/json'},
body: JSON.stringify({limit: 100, cursor: 'key_1234abcd'})
};
fetch('https://api.unkey.com/v2/portal.listKeys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.unkey.com/v2/portal.listKeys",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'limit' => 100,
'cursor' => 'key_1234abcd'
]),
CURLOPT_COOKIE => "portal_session=",
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}HttpResponse<String> response = Unirest.post("https://api.unkey.com/v2/portal.listKeys")
.header("cookie", "portal_session=")
.header("Content-Type", "application/json")
.body("{\n \"limit\": 100,\n \"cursor\": \"key_1234abcd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.unkey.com/v2/portal.listKeys")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["cookie"] = 'portal_session='
request["Content-Type"] = 'application/json'
request.body = "{\n \"limit\": 100,\n \"cursor\": \"key_1234abcd\"\n}"
response = http.request(request)
puts response.read_body{
"meta": {
"requestId": "req_123"
},
"data": [
{
"keyId": "key_1234567890abcdef",
"start": "sk_test_abc123",
"enabled": true,
"createdAt": 1701425400000,
"name": "Production API Key",
"meta": null,
"updatedAt": 1701425400000,
"lastUsedAt": 1701425400000,
"expires": 1735689600000,
"permissions": [
"documents.read",
"documents.write"
],
"roles": [
"editor",
"viewer"
],
"credits": {
"remaining": 1000,
"refill": {
"interval": "daily",
"amount": 1000,
"refillDay": 15
}
},
"identity": {
"id": "<string>",
"externalId": "<string>",
"meta": {},
"ratelimits": [
{
"id": "rl_1234567890abcdef",
"name": "api_requests",
"limit": 1000,
"duration": 3600000,
"autoApply": true
}
]
},
"plaintext": "sk_test_abc123def456",
"ratelimits": [
{
"id": "rl_1234567890abcdef",
"name": "api_requests",
"limit": 1000,
"duration": 3600000,
"autoApply": true
}
]
}
],
"pagination": {
"hasMore": true,
"cursor": "eyJrZXkiOiJrZXlfMTIzNCIsInRzIjoxNjk5Mzc4ODAwfQ=="
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found",
"errors": [
{
"location": "body.permissions[0].name",
"message": "Must be at least 3 characters long",
"fix": "Ensure the name uses only alphanumeric characters, underscores, and hyphens"
}
]
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}{
"meta": {
"requestId": "req_123"
},
"error": {
"detail": "Property foo is required but is missing.",
"status": 404,
"title": "Not Found",
"type": "https://unkey.com/docs/errors/unkey/resource/not_found"
}
}