Kernel Profiles API
Create, list, retrieve, and delete browser profiles.
Create, list, retrieve, and delete browser profiles.
openapi: 3.1.0
info:
title: Kernel API Keys Profiles API
description: Developer tools and cloud infrastructure for AI agents to use web browsers
version: 0.1.0
servers:
- url: https://api.onkernel.com
description: API Server
security:
- bearerAuth: []
tags:
- name: Profiles
description: Create, list, retrieve, and delete browser profiles.
paths:
/profiles:
post:
operationId: postProfiles
tags:
- Profiles
summary: Create a new profile
description: Create a browser profile that can be used to load state into future browser sessions.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileRequest'
responses:
'201':
description: Profile created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Profile'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'409':
$ref: '#/components/responses/Conflict'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\nconst profile = await client.profiles.create();\n\nconsole.log(profile.id);"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\nprofile = client.profiles.create()\nprint(profile.id)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tprofile, err := client.Profiles.New(context.TODO(), kernel.ProfileNewParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", profile.ID)\n}\n"
get:
operationId: getProfiles
tags:
- Profiles
summary: List profiles
description: List profiles with optional filtering and pagination.
security:
- bearerAuth: []
parameters:
- name: limit
in: query
required: false
description: Limit the number of profiles to return.
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: offset
in: query
required: false
description: Offset the number of profiles to return.
schema:
type: integer
minimum: 0
default: 0
- name: query
in: query
required: false
description: Case-insensitive substring match against profile name or ID.
schema:
type: string
- name: name
in: query
required: false
description: Exact-match filter on profile name using the database collation. In production, matching is case- and accent-insensitive. During the default-project migration, unscoped requests prefer a concrete default-project profile over a legacy unscoped profile with the same name.
schema:
type: string
responses:
'200':
description: List of profiles
headers:
X-Limit:
description: Limit the number of profiles to return.
schema:
type: integer
minimum: 1
maximum: 100
default: 20
X-Offset:
description: The offset of profiles to return.
schema:
type: integer
minimum: 0
default: 0
X-Next-Offset:
description: The offset where the next page starts. 0 when there are no more results.
schema:
type: integer
nullable: true
X-Has-More:
description: Whether there are more profiles to fetch.
schema:
type: boolean
default: false
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Profile'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\n// Automatically fetches more pages as needed.\nfor await (const profile of client.profiles.list()) {\n console.log(profile.id);\n}"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\npage = client.profiles.list()\npage = page.items[0]\nprint(page.id)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tpage, err := client.Profiles.List(context.TODO(), kernel.ProfileListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", page)\n}\n"
/profiles/{id_or_name}:
get:
operationId: getProfileByIdOrName
tags:
- Profiles
summary: Get profile by ID or name
description: Retrieve details for a single profile by its ID or name.
security:
- bearerAuth: []
parameters:
- name: id_or_name
in: path
required: true
schema:
type: string
description: Profile ID or name
responses:
'200':
description: Profile details
content:
application/json:
schema:
$ref: '#/components/schemas/Profile'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\nconst profile = await client.profiles.retrieve('id_or_name');\n\nconsole.log(profile.id);"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\nprofile = client.profiles.retrieve(\n \"id_or_name\",\n)\nprint(profile.id)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tprofile, err := client.Profiles.Get(context.TODO(), \"id_or_name\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", profile.ID)\n}\n"
patch:
operationId: patchProfileByIdOrName
tags:
- Profiles
summary: Rename profile by ID or name
description: Update a profile's name. Names must be unique within the logical project; during the default-project migration, unscoped profiles and profiles in the org default project are treated as the same project. Duplicate-name conflicts are checked before update but are best-effort because there is no backing unique index. Renaming a profile while a browser session references it by name may prevent that session's changes from saving; prefer renaming when the profile is not in use.
security:
- bearerAuth: []
parameters:
- name: id_or_name
in: path
required: true
schema:
type: string
description: Profile ID or profile name
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileUpdateRequest'
responses:
'200':
description: Profile updated
content:
application/json:
schema:
$ref: '#/components/schemas/Profile'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\nconst profile = await client.profiles.update('id_or_name', { name: 'my-renamed-profile' });\n\nconsole.log(profile.id);"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\nprofile = client.profiles.update(\n id_or_name=\"id_or_name\",\n name=\"my-renamed-profile\",\n)\nprint(profile.id)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tprofile, err := client.Profiles.Update(\n\t\tcontext.TODO(),\n\t\t\"id_or_name\",\n\t\tkernel.ProfileUpdateParams{\n\t\t\tName: \"my-renamed-profile\",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", profile.ID)\n}\n"
delete:
operationId: deleteProfileByIdOrName
tags:
- Profiles
summary: Delete profile by ID or name
description: Delete a profile by its ID or by its name.
security:
- bearerAuth: []
parameters:
- name: id_or_name
in: path
required: true
schema:
type: string
description: Profile ID or profile name
responses:
'204':
description: Profile deleted successfully
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\nawait client.profiles.delete('id_or_name');"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\nclient.profiles.delete(\n \"id_or_name\",\n)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\terr := client.Profiles.Delete(context.TODO(), \"id_or_name\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n"
/profiles/{id_or_name}/download:
get:
operationId: downloadProfileByIdOrName
tags:
- Profiles
summary: Download profile archive
description: Returns a zstd-compressed tar file of the full user-data directory.
security:
- bearerAuth: []
parameters:
- name: id_or_name
in: path
required: true
schema:
type: string
description: Profile ID or name
responses:
'200':
description: zstd-compressed tar archive of the user-data directory
content:
application/octet-stream:
schema:
type: string
format: binary
'202':
description: Profile exists but has not yet captured any state. Use it in a browser session first to capture state.
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
x-codeSamples:
- lang: JavaScript
source: "import Kernel from '@onkernel/sdk';\n\nconst client = new Kernel({\n apiKey: process.env['KERNEL_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.profiles.download('id_or_name');\n\nconsole.log(response);\n\nconst content = await response.blob();\nconsole.log(content);"
- lang: Python
source: "import os\nfrom kernel import Kernel\n\nclient = Kernel(\n api_key=os.environ.get(\"KERNEL_API_KEY\"), # This is the default and can be omitted\n)\nresponse = client.profiles.download(\n \"id_or_name\",\n)\nprint(response)\ncontent = response.read()\nprint(content)"
- lang: Go
source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/kernel/kernel-go-sdk\"\n\t\"github.com/kernel/kernel-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := kernel.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.Profiles.Download(context.TODO(), \"id_or_name\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response)\n}\n"
components:
responses:
Conflict:
description: Conflict – resource already exists
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalError:
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Unauthorized – missing or invalid authorization token
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: Bad Request – invalid input
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Forbidden – insufficient permissions or plan
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Error:
type: object
required:
- code
- message
properties:
code:
type: string
description: Application-specific error code (machine-readable)
example: bad_request
message:
type: string
description: Human-readable error description for debugging
example: 'Missing required field: app_name'
details:
type: array
description: Additional error details (for multiple errors)
items:
$ref: '#/components/schemas/ErrorDetail'
inner_error:
$ref: '#/components/schemas/ErrorDetail'
ProfileRequest:
type: object
description: Request body for creating a profile.
properties:
name:
type: string
description: Optional name of the profile. Must be unique within the logical project; during the default-project migration, unscoped profiles and profiles in the org default project are treated as the same project.
required: []
ProfileUpdateRequest:
type: object
required:
- name
properties:
name:
type: string
description: New profile name. Must be unique within the logical project; during the default-project migration, unscoped profiles and profiles in the org default project are treated as the same project.
minLength: 1
maxLength: 255
example: my-renamed-profile
Profile:
type: object
description: Browser profile metadata.
properties:
id:
type: string
description: Unique identifier for the profile
name:
type: string
nullable: true
description: Optional, easier-to-reference name for the profile
created_at:
type: string
format: date-time
description: Timestamp when the profile was created
updated_at:
type: string
format: date-time
description: Timestamp when the profile was last updated
last_used_at:
type: string
format: date-time
description: Timestamp when the profile was last used
required:
- id
- created_at
ErrorDetail:
type: object
properties:
code:
type: string
description: Lower-level error code providing more specific detail
example: invalid_input
message:
type: string
description: Further detail about the error
example: Provided version string is not semver compliant
securitySchemes:
bearerAuth:
type: http
scheme: bearer