PlanyDocs
API reference

ProjectService

api.plany.cloud:443Global6 methods

Create and manage projects, the containers everything you run lives in. Every game server, sandbox, network, secret and repository belongs to a project, and a project belongs to an account, which pays for it. Use projects to separate environments or games, and grant people access to one project without giving them the rest.

CreateProject

plany.project.v1.ProjectService/CreateProject

Creates a project. Fails with RESOURCE_EXHAUSTED if the account is at its projects-per-account quota, and with FAILED_PRECONDITION if the account has no credit.

Parameters

  • projectProjectRequired
    Show child attributes
    • display_namestringRequired
    • accountstringRequired

      Owning account, accounts/{account}. Changing it is a transfer, done through a dedicated flow rather than UpdateProject.

    • namestringIdentifier

      projects/{project}.

    • project_idstringImmutable

      Short id unique across Plany, e.g. "survival-eu". Appears in resource names and API URLs, so it is immutable once set.

    • labelsmap<string, string>

      Labels are copied onto every usage record the project generates, which is how a studio splits one bill across games, environments or customers.

    • default_locationstring

      Default location for resources created without an explicit one.

  • project_idstring

    Desired short id. Empty derives one from display_name, appending a suffix if that is taken.

  • request_idstring

Returns

Project.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"project": {
"display_name": "My server",
"account": "accounts/"
}
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/CreateProject
Example response
{
"name": "projects/",
"project_id": "my-project",
"display_name": "My server",
"account": "accounts/",
"state": "STATE_ACTIVE",
"labels": {
"key": ""
},
"default_location": "",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"purge_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\"",
"active_locations": [
""
]
}

GetProject

Read
plany.project.v1.ProjectService/GetProject

Parameters

  • namestringRequired

Returns

Project.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "projects/"
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/GetProject
Example response
{
"name": "projects/",
"project_id": "my-project",
"display_name": "My server",
"account": "accounts/",
"state": "STATE_ACTIVE",
"labels": {
"key": ""
},
"default_location": "",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"purge_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\"",
"active_locations": [
""
]
}

ListProjects

Read
plany.project.v1.ProjectService/ListProjects

Parameters

  • accountstring

    Restrict to one account. Empty lists every project the caller can see across all their accounts, which is what the console's project picker wants.

  • page_sizeint32
  • page_tokenstring
  • filterstring

    AIP-160 filter, e.g. state = "ACTIVE" AND labels.env = "prod".

  • order_bystring
  • show_deletedbool

    Include projects in PENDING_DELETION, which are hidden by default.

Returns

ListProjectsResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"page_size": 50
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/ListProjects
Example response
{
"projects": [
{
"name": "projects/",
"project_id": "my-project",
"display_name": "My server",
"account": "accounts/",
"state": "STATE_ACTIVE",
"labels": {
"key": ""
},
"default_location": "",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"purge_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\"",
"active_locations": [
""
]
}
],
"next_page_token": ""
}

UpdateProject

plany.project.v1.ProjectService/UpdateProject

Parameters

  • projectProjectRequired
    Show child attributes
    • display_namestringRequired
    • accountstringRequired

      Owning account, accounts/{account}. Changing it is a transfer, done through a dedicated flow rather than UpdateProject.

    • namestringIdentifier

      projects/{project}.

    • project_idstringImmutable

      Short id unique across Plany, e.g. "survival-eu". Appears in resource names and API URLs, so it is immutable once set.

    • labelsmap<string, string>

      Labels are copied onto every usage record the project generates, which is how a studio splits one bill across games, environments or customers.

    • default_locationstring

      Default location for resources created without an explicit one.

  • update_maskFieldMaskRequired

Returns

Project.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"project": {
"display_name": "My server",
"account": "accounts/"
},
"update_mask": "display_name"
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/UpdateProject
Example response
{
"name": "projects/",
"project_id": "my-project",
"display_name": "My server",
"account": "accounts/",
"state": "STATE_ACTIVE",
"labels": {
"key": ""
},
"default_location": "",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"purge_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\"",
"active_locations": [
""
]
}

DeleteProject

Long-running
plany.project.v1.ProjectService/DeleteProject

Begins project deletion.

The project enters STATE_PENDING_DELETION and can be restored with UndeleteProject until it is purged.

Parameters

  • namestringRequired
  • etagstring
  • disallow_non_emptybool

    Refuse the delete if the project still holds resources, instead of cascading. The safe default for scripted teardown.

  • validate_onlybool
  • request_idstring

    Idempotency key. A retry returns the original operation rather than starting a second teardown, which matters because deletion fans out across every region and running it twice would race with itself.

Returns

An Operation that resolves to Empty.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "projects/"
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/DeleteProject
Example response
{}

UndeleteProject

plany.project.v1.ProjectService/UndeleteProject

Parameters

  • namestringRequired

Returns

Project.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "projects/"
}' \
api.plany.cloud:443 plany.project.v1.ProjectService/UndeleteProject
Example response
{
"name": "projects/",
"project_id": "my-project",
"display_name": "My server",
"account": "accounts/",
"state": "STATE_ACTIVE",
"labels": {
"key": ""
},
"default_location": "",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"purge_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\"",
"active_locations": [
""
]
}

The DeleteProjectMetadata object

Attributes

DeleteProjectMetadata
{
"project": "projects/",
"locations": [
{
"location": "",
"resources_total": 0,
"resources_deleted": 0,
"error": ""
}
],
"current_step": ""
}

The DeleteProjectMetadata.LocationProgress object

Per-region teardown progress, so a stuck region is visible rather than hidden behind a single aggregate percentage.

Attributes

  • locationstring
  • resources_totalint32
  • resources_deletedint32
  • errorstring
DeleteProjectMetadata.LocationProgress
{
"location": "",
"resources_total": 0,
"resources_deleted": 0,
"error": ""
}

ListProjectsResponse

  • Show child attributes
    • display_namestringRequired
    • accountstringRequired

      Owning account, accounts/{account}. Changing it is a transfer, done through a dedicated flow rather than UpdateProject.

    • namestringIdentifier

      projects/{project}.

    • project_idstringImmutable

      Short id unique across Plany, e.g. "survival-eu". Appears in resource names and API URLs, so it is immutable once set.

    • stateProject.StateOutput only
      STATE_ACTIVESTATE_PENDING_DELETIONSTATE_SUSPENDED
    • labelsmap<string, string>

      Labels are copied onto every usage record the project generates, which is how a studio splits one bill across games, environments or customers.

    • default_locationstring

      Default location for resources created without an explicit one.

    • create_timeTimestampOutput only
    • update_timeTimestampOutput only
    • purge_timeTimestampOutput only

      When a pending deletion becomes irreversible.

    • etagstringOutput only
    • active_locationsrepeated stringOutput only

      Locations this project has resources in. Maintained by regional services so that a project-wide delete knows which regions to fan out to without asking every region in the fleet.

  • next_page_tokenstring

Project

Project groups resources, scopes quota and carries the labels that spend is broken down by.

  • display_namestringRequired
  • accountstringRequired

    Owning account, accounts/{account}. Changing it is a transfer, done through a dedicated flow rather than UpdateProject.

  • namestringIdentifier

    projects/{project}.

  • project_idstringImmutable

    Short id unique across Plany, e.g. "survival-eu". Appears in resource names and API URLs, so it is immutable once set.

  • stateProject.StateOutput only
    STATE_ACTIVESTATE_PENDING_DELETIONSTATE_SUSPENDED
  • labelsmap<string, string>

    Labels are copied onto every usage record the project generates, which is how a studio splits one bill across games, environments or customers.

  • default_locationstring

    Default location for resources created without an explicit one.

  • create_timeTimestampOutput only
  • update_timeTimestampOutput only
  • purge_timeTimestampOutput only

    When a pending deletion becomes irreversible.

  • etagstringOutput only
  • active_locationsrepeated stringOutput only

    Locations this project has resources in. Maintained by regional services so that a project-wide delete knows which regions to fan out to without asking every region in the fleet.

Enums

Project.State

ValueDescription
STATE_UNSPECIFIED
STATE_ACTIVE
STATE_PENDING_DELETIONDeletion requested, inside the retention window. Resources are stopped and billing has ceased, but everything is restorable.
STATE_SUSPENDEDOwning account has no credit. Workloads are stopped; the project itself is untouched and resumes on top-up.