> ## Documentation Index
> Fetch the complete documentation index at: https://gcore-doc-1256a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage a PostgreSQL server

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).filter(c => c && c.props && c.props.id);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    ## Create a server

    This guide describes how to create a PostgreSQL server.

    ### Before you begin

    Before you begin, make sure you have enough quotas to create a PostgreSQL cluster.

    1\. Go to **Cloud Management**, then **Quotas Viewer** and select the region.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-10.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=a8fb0245f67083282be65d0dde691cd2" alt="manage postgresql" width="1392" height="501" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-10.png" />
    </Frame>

    2\. On the **Database Service** tab, select the number of PostgreSQL clusters you need and specify the reason in the field on the right.

    3\. Click **Send request**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-20.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=80bbd1f8389eae5e34af924d242dbfed" alt="manage postgresql send quotas request" width="1470" height="803" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-20.png" />
    </Frame>

    Your request will be processed within fifteen minutes and the number of quotas will be increased.

    ### Create a server

    1\. In the Cloud menu, choose the Database for PostgreSQL tab and click **Create PostgreSQL server**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-30.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=d111f6d0a618f74b76f8b4fa25b4af5b" alt="manage postgresql create a server" width="4616" height="2812" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-30.png" />
    </Frame>

    2\. Choose the region where you want to host your PostgreSQL server.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-40.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=bdc775b779d91d70811f84a1cd3f4624" alt="manage postgresql choose region" width="622" height="386" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-40.png" />
    </Frame>

    3\. Choose the appropriate [PostgreSQL version](/cloud/managed-database-postgresql#supported-versions).

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-50.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=cae3fb7b6662e6a3c6f3bb04314a590b" alt="manage postgresql select version" width="622" height="82" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-50.png" />
    </Frame>

    4\. In **Compute**, select the server flavor. Optionally, you can set your own settings via text mode to enter specific database management system (DBMS) settings in the window that opens.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-60.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=befe8c071bb2f2726552a70837d86932" alt="manage postgresql select server flavor" width="824" height="205" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-60.png" />
    </Frame>

    5\. In **Storage**, choose the volume type and size.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-70.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=b4b8e8a5de97ec65e690bb06f9cceff7" alt="manage postgresql choose volume" width="622" height="166" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-70.png" />
    </Frame>

    6\. (Optionally) Switch on the **Enable High availability** toggle in **PG configuration** to deploy three replicas with the same configuration to ensure that your database remains accessible even in the event of a server failure. If you turn on this feature, select the appropriate replication mode:

    * Asynchronous: In asynchronous replication, servers work independently. The primary database sends the changes to the replicas and does not wait for confirmation that the changes have been applied. This mode is suitable for scenarios where data consistency with some level of delay is acceptable, though high performance is crucial.

    * Synchronous: In synchronous replication, the primary database must wait for confirmation that the changes have been applied in the replica databases. The changes are replicated in real time or near-real time. It provides full protection against data loss but may have lower performance.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-90.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=82d37d2e3b24d88500974ced3d43a8f6" alt="manage postgresql manage replication mode" width="798" height="196" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-90.png" />
    </Frame>

    You can enable or disable this feature later.

    7\. In **Network settings**, configure the network interface.

    Choose Public network and configure the Access control list to limit the access to your server to the specified IP addresses.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-100.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=d0eeff61bc9fb48217cf9876a24fd509" alt="manage postgresql manage network interface" width="829" height="410" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-100.png" />
    </Frame>

    **Note** : If you add *0.0.0.0/0*, you will allow unrestricted access to all IP addresses from the Internet. We strongly recommend using this setting only temporarily and exclusively on test servers without any sensitive data.

    8\. In **Authentication**, add your username.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-110-v2.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=9e7d9b0d9accb563fb9ed18fba22eff5" alt="manage postgresql manage authentication" width="2424" height="580" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-110-v2.png" />
    </Frame>

    9\. In **Server details**, specify the server name and database name.

    **Note** : The database size limit is 100 GB. This limit is for the beta stage only. If you need a more extensive database size during beta - please get in touch with [support](mailto:support@gcore.com).

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-120.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=c78292e8eb5a91342f8f2be1e7c54809" alt="manage postgresql specify server details" width="622" height="250" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-120.png" />
    </Frame>

    10\. Click **Create PostgreSQL server** in the window on the right-hand side.

    The server will be created in a few minutes.

    ## Get your credentials

    This guide explains how to obtain the password to start using your Postgres server and how to reset it if you forget it.

    1\. Go to the **Database for PostgreSQL** tab and select the server you need.

    2\. Click **Generate credentials**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-130.jpg?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=edd507795aa409ef950656b79a7036d0" alt="manage postgresql generate credentials" width="1030" height="390" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-130.jpg" />
    </Frame>

    3\. Copy and save the password now. Once you close the window you will not be able to recover it.

    **Note** : If you forget your password, you can only reset it. A new password will be generated, and the previous one will be deactivated.

    4\. Click **OK**.

    ## Upgrade the PostgreSQL version

    If your current PostgreSQL version is not the latest one, you can upgrade it.

    1\. Go to the **Database for PostgreSQL** tab and select the server you need.

    2\. On the **Overview** tab, click **Update** in the General info section.

    **Note** : if you use the latest version, the button will be absent.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-140.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=d648e9563061c1d31578cbb861d3b777" alt="manage postgresql update version" width="1999" height="978" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-140.png" />
    </Frame>

    3\. Select the version you need from the drop-down list and click **Update**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-145.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=69995108024c54119a6db35807f10463" alt="manage postgresql update version pop up" width="1026" height="516" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-145.png" />
    </Frame>

    ## Delete a server

    1\. Go to the **Database for PostgreSQL** tab and select the server you want to delete.

    2\. Click **Delete server**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-150.jpg?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=441f4b54dc3942f9b910bdbf3b4b4a81" alt="manage postgresql delete server" width="1030" height="390" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-150.jpg" />
    </Frame>

    3\. In the new window, type in *Delete* and click the **Delete server** button.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-160-v2.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=30208cac66e02925546117458f86d823" alt="manage postgresql confirm deletion" width="858" height="373" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-160-v2.png" />
    </Frame>

    ## Connect to a PostgreSQL server

    This guide explains what tools you can use to access your PostgreSQL server and how to connect using psql and pgAdmin.

    ### Before the beginning

    Before you connect to your PostgreSQL server, make sure to do the following:

    1\. Collect the connection details:

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-170.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=54f63e2967bff0ca9a52bd0412a421c9" alt="manage postgresql connection details" width="1305" height="621" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-170.png" />
    </Frame>

    * Endpoint. You can find it in the "Connection details"
    * Username. You can find it in the "Connection details"
    * Port. You can find it by copying the connection strings in the "Connection details"
    * Password. You should have got it separately after creating a server. If you forgot your password, [reset it](/cloud/managed-database-postgresql/manage-postgresql-servers#get-your-credentials).

    2\. Make sure your client computer is in the access control list of the PostgreSQL server. It means that the external IP address of PC which is trying to connect to PostgreSQL should be in allowlist (ACL).

    3\. Determine what tool you will use to connect to your server.

    * psql (Postgres Terminal Monitor): The command-line PostgreSQL client, that allows you to enter, edit, and execute SQL commands directly from your terminal or command prompt.

    * Native Frontend Tools (e.g., pgaccess, pgAdmin, ApplixWare): They provide graphical user interfaces (GUIs) for PostgreSQL database management. These tools offer a more user-friendly and visual way to create and manipulate databases.

    * Programming Languages (e.g., Perl, Tcl): These languages have supported interfaces for PostgreSQL. You can use these languages to write scripts or applications that connect to PostgreSQL databases programmatically. Some of the languages have convenient and powerful GUI toolkits which can help you construct custom applications. For example, pgaccess, mentioned above, is one of such applications written in Tcl/Tk.

    * C Programming with LIBPQ: If you're a C programmer, you can use the LIBPQ subroutine library to write C programs that connect to PostgreSQL databases. This allows you to submit SQL commands from your C program, retrieve results, and manage database interactions programmatically. The detailed information on using LIBPQ can be found in "[The PostgreSQL Programmer's Guide](https://www.postgresql.org/docs/7.3/programmer.html)."

    ### Connect using the psql client

    1\. [Download the PostgreSQL client](https://www.postgresql.org/download/) from the PostgreSQL website for your operating system in order to install psql.

    2\. Start psql by typing the following command in your terminal:

    ```sh theme={null}
    psql -h hostname -p port -d dbname -U username
    ```

    Replace `hostname`, `port`, `dbname`, and `username` with your custom values.

    3\. Enter the password and press **Enter**.

    For more details, refer to the [PostgreSQL official documentation](https://www.postgresql.org/docs/).

    ### Connect using pgAdmin

    1\. [Download](https://www.pgadmin.org/) and install pgAdmin to your client computer.

    2\. Launch pgAdmin.

    3\. On the **Dashboard** tab, choose **Add New Server**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-180.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=69f2b5107b9b9439e36f239d8779c731" alt="manage postgresql connect phpmyadmin 1" width="900" height="511" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-180.png" />
    </Frame>

    4\. In the Create - Server dialog box that appears, type the server's name in the **General** tab and click **Save**.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=2c9794a179d22348224faebd6e724fde" alt="manage postgresql connect phpmyadmin 2" width="564" height="619" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png" />
    </Frame>

    5\. Go to the **Connection** tab and enter the host (endpoint,) port, username, and password in the relevant fields.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/O2fvsv9KLjD8CjMq/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png?fit=max&auto=format&n=O2fvsv9KLjD8CjMq&q=85&s=2c9794a179d22348224faebd6e724fde" alt="manage postgresql connect phpmyadmin 3" width="564" height="619" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png" />
    </Frame>

    6\. Click **Save**.

    7\. Locate the server you've added in the left-side menu and click it to access. For more details, refer to the [pgAdmin official documentation](https://www.pgadmin.org/docs/).
  </MethodSection>

  <MethodSection id="api" label="REST API">
    Gcore Managed PostgreSQL provisions a fully managed database cluster with automatic backups and optional High Availability replication. Four API calls create the cluster, poll the creation task, retrieve the connection string, and expose credentials for a psql session.

    <Info>
      A permanent [API token](/developer-tools/rest-api/authentication) is required, along with a [project ID](https://api.gcore.com/docs/cloud#tag/Projects/operation/GetProjectList.get) and a [region ID](https://api.gcore.com/docs/cloud#tag/Regions/operation/GetRegionList.get).
    </Info>

    Open a bash terminal and set these as environment variables before running the examples:

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export GCORE_CLOUD_PROJECT_ID="{YOUR_PROJECT_ID}"
    export GCORE_CLOUD_REGION_ID="{YOUR_REGION_ID}"
    ```

    ## Step 1. Activate the PostgreSQL service

    The Managed PostgreSQL service requires a one-time activation per project and region before any clusters can be created.

    ```bash theme={null}
    curl -s -X PUT "https://api.gcore.com/cloud/v1/dbaas/status/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
      -H "Authorization: APIKey $GCORE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"is_initialized": true}'
    ```

    The API returns:

    ```json theme={null}
    {
      "is_initialized": true
    }
    ```

    To check whether activation is already done, call <code>GET /cloud/v1/dbaas/status/{project_id}/{region_id}</code> - if `is_initialized` is already `true`, skip this step.

    ## Step 2. Create the cluster

    A single create call provisions the database server, configures network access, creates an initial user, and creates the first database.

    | Parameter                         | Required | Description                                                                                                                     |
    | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
    | `cluster_name`                    | Yes      | Cluster identifier. Pattern `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`, max 50 characters                                                |
    | `pg_server_configuration.version` | Yes      | PostgreSQL major version. Supported values: `"15"`, `"14"`, `"13"`                                                              |
    | `pg_server_configuration.pg_conf` | Yes      | Custom `postgresql.conf` settings as a string. Pass `""` to use defaults                                                        |
    | `flavor.cpu`                      | Yes      | Number of vCPUs allocated to the instance                                                                                       |
    | `flavor.memory_gib`               | Yes      | RAM in GiB                                                                                                                      |
    | `storage.type`                    | Yes      | Block storage type. Use `ssd-hiiops` for best performance                                                                       |
    | `storage.size_gib`                | Yes      | Storage size in GiB. Maximum 100 GiB                                                                                            |
    | `network.acl`                     | Yes      | Allowed source IP addresses in CIDR notation. Use the connecting machine's public IP                                            |
    | `high_availability`               | Yes      | Set to `null` for a single-node cluster, or `{"replication_mode": "sync"}` or `{"replication_mode": "async"}` for three-node HA |
    | `users[].name`                    | No       | Initial database user. Lowercase letters only                                                                                   |
    | `users[].role_attributes`         | No       | PostgreSQL role attributes. Include `"CREATEDB"` to allow creating databases from psql                                          |
    | `databases[].name`                | No       | Initial database name. Lowercase letters only. Must reference a user in `users[]` as `owner`                                    |

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ["GCORE_API_KEY"])
        task_id_list = client.cloud.databases.postgres.clusters.create(
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
            cluster_name="my-postgres",
            pg_server_configuration={"version": "15", "pg_conf": ""},
            flavor={"cpu": 2, "memory_gib": 4},
            storage={"type": "ssd-hiiops", "size_gib": 10},
            network={
                "network_type": "public",
                "acl": ["{YOUR_IP_ADDRESS}/32"],
            },
            high_availability=None,
            users=[{"name": "dbuser", "role_attributes": ["INHERIT", "LOGIN", "CREATEDB"]}],
            databases=[{"name": "mydb", "owner": "dbuser"}],
        )
        print(task_id_list.tasks[0])
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X POST "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
          -H "Authorization: APIKey $GCORE_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "cluster_name": "my-postgres",
            "pg_server_configuration": {
              "version": "15",
              "pg_conf": ""
            },
            "flavor": {
              "cpu": 2,
              "memory_gib": 4
            },
            "storage": {
              "type": "ssd-hiiops",
              "size_gib": 10
            },
            "network": {
              "network_type": "public",
              "acl": ["{YOUR_IP_ADDRESS}/32"]
            },
            "high_availability": null,
            "users": [
              {"name": "dbuser", "role_attributes": ["INHERIT", "LOGIN", "CREATEDB"]}
            ],
            "databases": [
              {"name": "mydb", "owner": "dbuser"}
            ]
          }'
        ```

        Response:

        ```json theme={null}
        {
          "tasks": ["bce1a2e8-d40b-4aca-bbad-fa2c3580cf20"]
        }
        ```
      </Tab>
    </Tabs>

    ```bash theme={null}
    export TASK_ID="{TASK_ID}"
    ```

    ## Step 3. Poll the task

    Cluster creation takes 3-5 minutes. Poll every 5 seconds until `state` is `FINISHED`.

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        task = client.cloud.tasks.poll(
            task_id_list.tasks[0],
            polling_interval_seconds=5,
            polling_timeout_seconds=600,
        )
        print("Cluster ready:", task.created_resources.postgresql_clusters[0])
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s "https://api.gcore.com/cloud/v1/tasks/$TASK_ID" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        When complete:

        ```json theme={null}
        {
          "id": "bce1a2e8-d40b-4aca-bbad-fa2c3580cf20",
          "state": "FINISHED",
          "created_resources": {
            "postgresql_clusters": ["my-postgres"]
          }
        }
        ```
      </Tab>
    </Tabs>

    ## Step 4. Get the connection string

    The cluster detail response includes the host, network configuration, and a connection string template in `network.connection_string`. The password field is masked - retrieve it in Step 5.

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        cluster = client.cloud.databases.postgres.clusters.get(
            cluster_name="my-postgres",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print("Status:", cluster.status)
        print("Host:", cluster.network.host)
        print("Connection string:", cluster.network.connection_string)
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        CLUSTER_NAME="my-postgres"

        curl -s "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {
          "cluster_name": "my-postgres",
          "status": "READY",
          "network": {
            "network_type": "public",
            "acl": ["{YOUR_IP_ADDRESS}/32"],
            "host": "my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev",
            "connection_string": "postgres://dbuser:*****@my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev:5432/mydb"
          },
          "flavor": {"cpu": 2, "memory_gib": 4},
          "storage": {"size_gib": 10, "type": "ssd-hiiops"},
          "pg_server_configuration": {"version": "15"},
          "users": [{"name": "dbuser", "is_secret_revealed": false}],
          "databases": [{"name": "mydb", "owner": "dbuser"}]
        }
        ```
      </Tab>
    </Tabs>

    ```bash theme={null}
    export CLUSTER_NAME="my-postgres"
    export PG_HOST="my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev"
    ```

    ## Step 5. Retrieve credentials

    The credentials endpoint reveals the user password. It can only be called once per user - the password is not stored by Gcore afterward. The second call returns an error.

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        creds = client.cloud.databases.postgres.clusters.user_credentials.get(
            username="dbuser",
            cluster_name="my-postgres",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(creds.username)
        print(creds.password)  # save immediately - second call raises an error
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        USERNAME="dbuser"

        curl -s "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME/users/$USERNAME/credentials" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {
          "username": "dbuser",
          "password": "8T8WieWrkMSvrHlLlnAVtJDV4Vhyxz7..."
        }
        ```
      </Tab>
    </Tabs>

    <Warning>
      Calling this endpoint a second time returns: `"Requested credentials already revealed. You must regenerate credentials"`. To reset the password, call <code>POST /cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials</code>.
    </Warning>

    ## Step 6. Connect with psql

    With the host and password from the previous steps, open a psql session. Set the password via the `PGPASSWORD` environment variable to avoid an interactive prompt.

    ```bash theme={null}
    export PGPASSWORD="{PASSWORD}"

    psql -h $PG_HOST -p 5432 -U dbuser -d mydb
    ```

    ```
    psql (15.x)
    SSL connection (protocol: TLSv1.3, ...)
    Type "help" for help.

    mydb=#
    ```

    Verify the connection and create a table:

    ```sql theme={null}
    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        name TEXT NOT NULL,
        created_at TIMESTAMPTZ DEFAULT NOW()
    );

    \dt
    ```

    ```
            List of relations
     Schema | Name  | Type  | Owner
    --------+-------+-------+--------
     public | users | table | dbuser
    (1 row)
    ```
  </MethodSection>
</MethodSwitch>
