---
title: "Issue one time-bound PostgreSQL credential for Dev or Prod"
method: POST
path: "/v1/projects/{project_id}/database/access"
---

# Issue one time-bound PostgreSQL credential for Dev or Prod

`POST /v1/projects/{project_id}/database/access`

## Request

- Base URL: `https://app.ohmyho.st`
- URL: `https://app.ohmyho.st/v1/projects/{project_id}/database/access`
- Auth: HTTP bearer

Owner-authorized direct PostgreSQL login for the project's own database, returned exactly once and never retrievable again. Mode read joins the read-only role, mode write joins the same restricted runtime role the application uses; neither can change schema, and application row-level security policies remain effective. The lifetime is 5 minutes to 24 hours (3600 seconds by default) and PostgreSQL refuses new logins after it; the platform ends remaining sessions within 15 minutes after expiry, at the latest. At most three active credentials exist per project environment. Database compute wakes and is metered normally, and existing credit grace and Stop budgets apply. Revoke the credential as soon as the work is finished and never store the connection URI in files, notes or source.

## Path parameters

- `project_id` string, required

## Headers

- `X-Request-Id` string

## Request body

- ProjectDatabaseAccessRequest
  - `environment` 'dev' | 'prod', required
  - `mode` 'read' | 'write': read joins the read-only role; write joins the restricted runtime role. Neither can change schema.
  - `ttl_seconds` integer: Credential lifetime between 5 minutes and 24 hours.
  - `label` string, nullable: Optional customer label without control characters or surrounding whitespace.

## Response `201`

The connection URI is returned once and is never persisted in plaintext.

- ProjectDatabaseAccessCredential
  - `access_id` string, required
  - `environment` 'dev' | 'prod', required
  - `mode` 'read' | 'write', required
  - `role_name` string, required
  - `host` string, required
  - `database` 'neondb', required
  - `label` string, nullable, required
  - `state` 'active' | 'expired' | 'revoked', required
  - `issued_at` string, date-time, required
  - `expires_at` string, date-time, required
  - `revoked_at` string, date-time, nullable, required
  - `revocation_reason` 'principal' | 'expired' | 'budget' | 'creation_failed' | 'data_change' | 'null', nullable, required
  - `connection_uri` string, uri, required: Returned exactly once. Use it immediately and never store it in files, notes or source.
  - `psql_command` string, required: The same credential as a ready psql invocation.

## Other responses

- `400`: The request failed.
- `401`: The request failed.
- `402`: The request failed.
- `404`: The resource does not exist or is not visible to the authenticated principal.
- `409`: The request failed.
- `429`: The request failed.
- `503`: The request failed.

---

[API](https://skmtc.dev/ohmyho/apis/ohmyho-st-api.md) · [All operations](https://skmtc.dev/ohmyho/apis/ohmyho-st-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ohmyho/apis/ohmyho-st-api/revisions/d069888c0017?raw)
