PlanyDocs
API reference

EncoreService

api.plany.cloud:443Global27 methods

Keep a finished game playable, with its servers funded by its own players through your Steam store. You connect your publisher account, declare an Encore for the game, move its servers into a project of their own, and set the offers players can buy. Four methods are anonymous and are called by the game itself: a player is proven by a Steam auth ticket, and the Encore is named by the encore_key that ships in the game.

ListSettlements

Read
plany.encore.v1.EncoreService/ListSettlements

Lists what a developer has paid Plany for credit already issued.

Parameters

  • parentstringRequired
  • page_sizeint32
  • page_tokenstring

Returns

ListSettlementsResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts//distributorLinks/my-distributor-link",
"page_size": 50
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/ListSettlements
Example response
{
"settlements": [
{
"name": "accounts//distributorLinks/my-distributor-link/settlements/my-settlement",
"amount": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"note": "",
"recorded_by": "",
"create_time": "2026-10-04T12:00:00Z"
}
],
"next_page_token": ""
}

CreateEncore

plany.encore.v1.EncoreService/CreateEncore

Declares a game end of life, and starts verifying it.

Returns at once in STATE_VERIFYING; the evidence is gathered in the background and the Encore moves to VERIFIED or NEEDS_REVIEW on its own. Nothing about the game changes here — no project, no move. A developer may transfer before verification finishes; players may not fund it until it has.

Parameters

  • parentstringRequired
  • encoreEncoreRequired
    Show child attributes
    • gamestringRequiredImmutable

      The game, in the Game Registry: accounts/{account}/games/{game}.

    • distributor_linkstringRequiredImmutable

      The publisher link that sells this game.

    • listingListingRequiredImmutable

      The product on the link's storefront. Must be one of its listings.

      Show child attributes
      • distributorDistributorRequired
        DISTRIBUTOR_STEAM
      • product_idstringRequired

        The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

    • funding_visibilityFundingVisibilityRequired
      FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
    • namestringIdentifier
    • display_namestring
    • etagstring
  • encore_idstringRequired

Returns

Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts/",
"encore": {
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE"
},
"encore_id": "my-encore"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/CreateEncore
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

GetEncore

Read
plany.encore.v1.EncoreService/GetEncore

Parameters

  • namestringRequired

Returns

Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/GetEncore
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

ListEncores

Read
plany.encore.v1.EncoreService/ListEncores

Lists your account's Encores. filter accepts a state, e.g. state = "NEEDS_REVIEW".

Parameters

  • parentstringRequired
  • page_sizeint32
  • page_tokenstring
  • filterstring

    state = "<STATE>", e.g. state = "NEEDS_REVIEW", and nothing else yet.

Returns

ListEncoresResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts/",
"page_size": 50
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/ListEncores
Example response
{
"encores": [
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}
],
"next_page_token": ""
}

UpdateEncore

plany.encore.v1.EncoreService/UpdateEncore

Updates display_name and funding_visibility.

Parameters

  • encoreEncoreRequired
    Show child attributes
    • gamestringRequiredImmutable

      The game, in the Game Registry: accounts/{account}/games/{game}.

    • distributor_linkstringRequiredImmutable

      The publisher link that sells this game.

    • listingListingRequiredImmutable

      The product on the link's storefront. Must be one of its listings.

      Show child attributes
      • distributorDistributorRequired
        DISTRIBUTOR_STEAM
      • product_idstringRequired

        The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

    • funding_visibilityFundingVisibilityRequired
      FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
    • namestringIdentifier
    • display_namestring
    • etagstring
  • update_maskFieldMaskRequired

    display_name and funding_visibility.

Returns

Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"encore": {
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE"
},
"update_mask": "display_name"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/UpdateEncore
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

DeleteEncore

plany.encore.v1.EncoreService/DeleteEncore

Deletes an Encore that has not been transferred.

After a transfer there is a project players paid into, and deleting the thing that explains it would leave a top-up-only project nobody can account for.

Parameters

  • namestringRequired

Returns

Empty.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/DeleteEncore
Example response
{}

RetryVerification

plany.encore.v1.EncoreService/RetryVerification

Gathers the evidence again, for an Encore waiting on review or declined.

Parameters

  • namestringRequired

Returns

Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/RetryVerification
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

PlanTransfer

plany.encore.v1.EncoreService/PlanTransfer

Proposes a transfer without doing anything.

Every component the game has in the source project, with the ones that belong to it pre-selected and the ones a shipped client may address by name flagged — and whether the project could be converted as it stands.

Parameters

  • namestringRequired
  • source_projectstringRequired

    The project the game's components are in now.

Returns

TransferPlan.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore",
"source_project": "projects/"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/PlanTransfer
Example response
{
"candidates": [
{
"type": "",
"name": "",
"display_name": "My server",
"location": "",
"belongs_to_game": false,
"client_facing": false,
"movable": false,
"note": ""
}
],
"recommended_mode": "MODE_CONVERT",
"explanation": "",
"warnings": [
""
]
}

StartTransfer

Long-running
plany.encore.v1.EncoreService/StartTransfer

Gives the Encore its project, by converting one or by moving into a new one.

Long-running. Follow its progress by reading the Encore with GetEncore: it carries the same Transfer as the operation's metadata, updated as each resource moves.

Parameters

  • namestringRequired
  • source_projectstringRequired
  • modeTransfer.ModeRequired
    MODE_CONVERTMODE_MOVE
  • resourcesrepeated string

    The candidates to move, by name. Refused for CONVERT, where the project goes whole and must hold nothing else.

  • acknowledge_warningsbool

    Required for MOVE: the caller has read TransferPlan.warnings.

  • request_idstring

Returns

An Operation that resolves to Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore",
"source_project": "projects/",
"mode": "MODE_CONVERT"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/StartTransfer
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

AcknowledgeTransferItem

plany.encore.v1.EncoreService/AcknowledgeTransferItem

Accepts what a transfer cannot preserve for one item, and lets it continue.

Parameters

  • namestringRequired
  • sourcestringRequired

    TransferItem.source.

Returns

Encore.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore",
"source": ""
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/AcknowledgeTransferItem
Example response
{
"name": "accounts//encores/my-encore",
"uid": "0b6f3c1e-8a2d-4f6e-9c1a-2f4b7d9e0a11",
"display_name": "My server",
"game": "",
"distributor_link": "accounts//distributorLinks/my-distributor-link",
"listing": {
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
},
"encore_key": "",
"state": "STATE_VERIFYING",
"verification": {
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
},
"project": "projects/",
"transfer": {
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
},
"funding_visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z",
"etag": "W/\"1\""
}

GetFunding

Read
plany.encore.v1.EncoreService/GetFunding

The project's money, as its developer sees it.

Parameters

  • namestringRequired

Returns

Funding.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/GetFunding
Example response
{
"encore": "",
"project": "projects/",
"balance": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"recent_spend": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"spend_window": "300s",
"runway": "300s",
"funded": false,
"purchases": "0",
"reversals": "0",
"purchased": {
"currency_code": "USD",
"units": "5",
"nanos": 0
}
}

CreateOffer

plany.encore.v1.EncoreService/CreateOffer

Parameters

  • parentstringRequired
  • offerOfferRequired
    Show child attributes
    • display_namestringRequired

      Shown in the Steam overlay when a player confirms a purchase.

    • priceMoneyRequired

      What the player pays, in USD. Steam converts to the player's own currency.

    • creditMoneyRequired

      What the project is credited, in USD.

      At most the price less the distributor's share. The developer is paid the net and owes Plany the credit, so a credit above the net is a developer owing more than they received on every sale.

    • namestringIdentifier
    • descriptionstring
    • activebool

      Whether players can buy it now. Every offer is created active; deactivate one with UpdateOffer.

  • offer_idstringRequired

Returns

Offer.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts//encores/my-encore",
"offer": {
"display_name": "My server",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
}
},
"offer_id": "my-offer"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/CreateOffer
Example response
{
"name": "accounts//encores/my-encore/offers/my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"active": false,
"item_id": "0",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z"
}

GetOffer

Read
plany.encore.v1.EncoreService/GetOffer

Parameters

  • namestringRequired

Returns

Offer.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore/offers/my-offer"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/GetOffer
Example response
{
"name": "accounts//encores/my-encore/offers/my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"active": false,
"item_id": "0",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z"
}

ListOffers

Read
plany.encore.v1.EncoreService/ListOffers

Parameters

  • parentstringRequired
  • page_sizeint32
  • page_tokenstring

Returns

ListOffersResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts//encores/my-encore",
"page_size": 50
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/ListOffers
Example response
{
"offers": [
{
"name": "accounts//encores/my-encore/offers/my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"active": false,
"item_id": "0",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z"
}
],
"next_page_token": ""
}

UpdateOffer

plany.encore.v1.EncoreService/UpdateOffer

Updates an offer. A price change applies to purchases begun afterwards; one already open with the distributor settles at the price it was opened at.

Parameters

  • offerOfferRequired
    Show child attributes
    • display_namestringRequired

      Shown in the Steam overlay when a player confirms a purchase.

    • priceMoneyRequired

      What the player pays, in USD. Steam converts to the player's own currency.

    • creditMoneyRequired

      What the project is credited, in USD.

      At most the price less the distributor's share. The developer is paid the net and owes Plany the credit, so a credit above the net is a developer owing more than they received on every sale.

    • namestringIdentifier
    • descriptionstring
    • activebool

      Whether players can buy it now. Every offer is created active; deactivate one with UpdateOffer.

  • update_maskFieldMaskRequired

    display_name, description, price, credit and active.

Returns

Offer.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"offer": {
"display_name": "My server",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
}
},
"update_mask": "display_name"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/UpdateOffer
Example response
{
"name": "accounts//encores/my-encore/offers/my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"active": false,
"item_id": "0",
"create_time": "2026-10-04T12:00:00Z",
"update_time": "2026-10-04T12:00:00Z"
}

DeleteOffer

plany.encore.v1.EncoreService/DeleteOffer

Deletes an offer nobody has bought. One with purchases is deactivated instead, because a purchase has to keep naming what was bought — and its offer_id stays taken. Read the offer afterwards to tell which happened.

Parameters

  • namestringRequired

Returns

Empty.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore/offers/my-offer"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/DeleteOffer
Example response
{}

GetPurchase

Read
plany.encore.v1.EncoreService/GetPurchase

Parameters

  • namestringRequired

Returns

Purchase.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//encores/my-encore/purchases/my-purchase"
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/GetPurchase
Example response
{
"name": "accounts//encores/my-encore/purchases/my-purchase",
"offer": "accounts//encores/my-encore/offers/my-offer",
"order_id": "my-order",
"player_id": "my-player",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"state": "STATE_INITIATED",
"state_message": "",
"ledger_entry": "",
"sandbox": false,
"create_time": "2026-10-04T12:00:00Z",
"credit_time": "2026-10-04T12:00:00Z",
"reverse_time": "2026-10-04T12:00:00Z"
}

ListPurchases

Read
plany.encore.v1.EncoreService/ListPurchases

Parameters

  • parentstringRequired
  • page_sizeint32
  • page_tokenstring

Returns

ListPurchasesResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"parent": "accounts//encores/my-encore",
"page_size": 50
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/ListPurchases
Example response
{
"purchases": [
{
"name": "accounts//encores/my-encore/purchases/my-purchase",
"offer": "accounts//encores/my-encore/offers/my-offer",
"order_id": "my-order",
"player_id": "my-player",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"credit": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"state": "STATE_INITIATED",
"state_message": "",
"ledger_entry": "",
"sandbox": false,
"create_time": "2026-10-04T12:00:00Z",
"credit_time": "2026-10-04T12:00:00Z",
"reverse_time": "2026-10-04T12:00:00Z"
}
],
"next_page_token": ""
}

GetPublicFunding

Read
plany.encore.v1.EncoreService/GetPublicFunding

What a game may show its players about the servers' funding.

Anonymous. Shaped by Encore.funding_visibility, and names no account.

Parameters

  • encore_keystringRequired

Returns

PublicFunding.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"encore_key": ""
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/GetPublicFunding
Example response
{
"funded": false,
"balance": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"runway_days": "0",
"visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"purchasable": false,
"unavailable_reason": ""
}

ListPublicOffers

Read
plany.encore.v1.EncoreService/ListPublicOffers

The offers a game may put in its store.

Anonymous. Lists active offers even while the Encore is not yet verified, with purchasable false, so a game can build its store before launch.

Parameters

  • encore_keystringRequired

Returns

ListPublicOffersResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"encore_key": ""
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/ListPublicOffers
Example response
{
"offers": [
{
"offer_id": "my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
}
}
],
"purchasable": false,
"unavailable_reason": ""
}

BeginPurchase

plany.encore.v1.EncoreService/BeginPurchase

Opens a purchase with the distributor. The Steam overlay appears for the player immediately after this returns.

Anonymous. The player is proven by auth_ticket and nothing else; the price and the credit are the offer's, and are never taken from the request. Refused before the distributor is called when the Encore is not verified, the offer is inactive, or the publisher's outstanding limit would be exceeded — so no player is charged for credit Plany will not issue.

Parameters

  • encore_keystringRequired
  • offer_idstringRequired

    PublicOffer.offer_id.

  • auth_ticketstringRequired

    The player's proof of who they are. For Steam, the hex encoding of a ticket from ISteamUser::GetAuthTicketForWebApi("plany-encore").

  • languagestring

    ISO 639-1, for the overlay's text. Defaults to English.

  • request_idstring

    Makes a retry safe. A second call with the same id for the same Encore returns the purchase the first opened rather than opening a second order — without it a game cannot retry this call at all, because an ambiguous failure may already have put an order in front of the player.

Returns

BeginPurchaseResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"encore_key": "",
"offer_id": "my-offer",
"auth_ticket": ""
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/BeginPurchase
Example response
{
"purchase": "",
"order_id": "my-order"
}

CompletePurchase

plany.encore.v1.EncoreService/CompletePurchase

Settles a purchase after the player answered in the overlay.

Anonymous, and safe to call more than once or not at all: the platform settles an approved order on its own if a game crashes before calling this, and a decline is confirmed with the distributor rather than taken from the request.

Parameters

  • encore_keystringRequired
  • purchasestringRequired
  • order_idstringRequired
  • authorizedboolRequired

    What the overlay reported. A false is confirmed with the distributor before the purchase is cancelled.

Returns

CompletePurchaseResponse.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"encore_key": "",
"purchase": "",
"order_id": "my-order",
"authorized": false
}' \
api.plany.cloud:443 plany.encore.v1.EncoreService/CompletePurchase
Example response
{
"state": "STATE_INITIATED",
"funding": {
"funded": false,
"balance": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"runway_days": "0",
"visibility": "FUNDING_VISIBILITY_EXACT_BALANCE",
"purchasable": false,
"unavailable_reason": ""
}
}

The Evidence object

Evidence is one thing verification found.

Attributes

  • KIND_STORE_UNAVAILABLEKIND_OWNERSHIPKIND_ANNOUNCEMENTKIND_OPERATOR
  • urlstring

    Where it was found.

  • quotestring

    The words, verbatim, for an announcement. Checked against the post before it is recorded: a quote the model produced that is not in the post is discarded, never shown.

  • detailstring

    A sentence of context, e.g. the store's own availability text.

  • observed_timeTimestamp
Evidence
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}

The Listing object

Listing is one product on one storefront.

Attributes

  • distributorDistributorRequired
    DISTRIBUTOR_STEAM
  • product_idstringRequired

    The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

  • display_namestringOutput only

    The storefront's own name for it, when Plany has read one.

Listing
{
"distributor": "DISTRIBUTOR_STEAM",
"product_id": "my-product",
"display_name": "My server"
}

The PublicOffer object

PublicOffer is an offer as a game shows it.

Attributes

  • offer_idstring

    The offer's own id, to pass to BeginPurchase.

  • display_namestring
  • descriptionstring
  • priceMoney
PublicOffer
{
"offer_id": "my-offer",
"display_name": "My server",
"description": "",
"price": {
"currency_code": "USD",
"units": "5",
"nanos": 0
}
}

The Settlement object

accounts//distributorLinks/{{distributor_link}}/settlements/{{settlement}}

Settlement is a developer paying Plany for credit already issued.

Attributes

  • namestringIdentifier
  • amountMoney
  • notestring
  • recorded_bystring
  • create_timeTimestamp
Settlement
{
"name": "accounts//distributorLinks/my-distributor-link/settlements/my-settlement",
"amount": {
"currency_code": "USD",
"units": "5",
"nanos": 0
},
"note": "",
"recorded_by": "",
"create_time": "2026-10-04T12:00:00Z"
}

The SteamCredential object

SteamCredential is how Plany acts as a Steamworks publisher.

Attributes

  • publisher_keystringInput onlyRequired

    A Steamworks publisher Web API key with Microtransaction permission.

    Write-only. Sealed before it is stored and never returned by any call: it can refund every order the publisher has ever taken.

  • sandboxboolImmutable

    Use ISteamMicroTxnSandbox. Orders are not charged and credit nothing, which is the whole integration minus the money.

  • publisher_key_fingerprintstringOutput only

    A fingerprint of the key, so a rotation can be seen to have happened: the first 16 hexadecimal characters of the SHA-256 of the key as sent. A client holding a key can compute it and compare without the key ever being read back.

SteamCredential
{
"sandbox": false,
"publisher_key_fingerprint": ""
}

The Transfer object

Transfer is how an Encore came to have a project.

Attributes

  • MODE_CONVERTMODE_MOVE
  • STATE_RUNNINGSTATE_SUCCEEDEDSTATE_FAILED
  • source_projectstring
  • Show child attributes
    • typestring

      The resource type, e.g. playpute.plany.cloud/GameServer.

    • sourcestring
    • destinationstring
    • STATE_PENDINGSTATE_RUNNINGSTATE_SUCCEEDEDSTATE_FAILEDSTATE_NEEDS_ACKNOWLEDGEMENT
    • messagestring
    • client_facingbool

      Something a shipped game client may address by name. Moving it changes that name, so a client nobody can patch stops reaching it.

  • messagestring
  • start_timeTimestamp
  • end_timeTimestamp
Transfer
{
"mode": "MODE_CONVERT",
"state": "STATE_RUNNING",
"source_project": "",
"items": [
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}
],
"message": "",
"start_time": "2026-10-04T12:00:00Z",
"end_time": "2026-10-04T12:00:00Z"
}

The TransferCandidate object

TransferCandidate is one resource a transfer could take.

Attributes

  • typestring

    e.g. playpute.plany.cloud/GameServer.

  • namestring
  • display_namestring
  • locationstring
  • belongs_to_gamebool

    Found through the game itself, rather than only by being in the project.

  • client_facingbool

    A shipped game client may address it by name.

  • movablebool

    Whether a move of this type is supported. A candidate that is not is listed so the plan can say why CONVERT is not available, never silently left behind.

  • notestring
TransferCandidate
{
"type": "",
"name": "",
"display_name": "My server",
"location": "",
"belongs_to_game": false,
"client_facing": false,
"movable": false,
"note": ""
}

The TransferItem object

TransferItem is one resource moving into an Encore project.

Attributes

  • typestring

    The resource type, e.g. playpute.plany.cloud/GameServer.

  • sourcestring
  • destinationstring
  • STATE_PENDINGSTATE_RUNNINGSTATE_SUCCEEDEDSTATE_FAILEDSTATE_NEEDS_ACKNOWLEDGEMENT
  • messagestring
  • client_facingbool

    Something a shipped game client may address by name. Moving it changes that name, so a client nobody can patch stops reaching it.

TransferItem
{
"type": "",
"source": "",
"destination": "",
"state": "STATE_PENDING",
"message": "",
"client_facing": false
}

The Verification object

Verification is what Plany found, and who decided.

Attributes

  • Show child attributes
    • KIND_STORE_UNAVAILABLEKIND_OWNERSHIPKIND_ANNOUNCEMENTKIND_OPERATOR
    • urlstring

      Where it was found.

    • quotestring

      The words, verbatim, for an announcement. Checked against the post before it is recorded: a quote the model produced that is not in the post is discarded, never shown.

    • detailstring

      A sentence of context, e.g. the store's own availability text.

    • observed_timeTimestamp
  • summarystring

    Why the platform did or did not decide on its own, in a sentence.

  • unknown_signalsrepeated string

    Signals that could not be read, by name. A signal that could not be read is not a signal that fell short, and a reviewer needs to know which.

  • modelstring

    The model that read the announcements, when one did.

  • decided_bystring

    encore.plany.cloud for an automatic decision, or the person at Plany who reviewed it.

  • reasonstring

    The reviewer's own sentence, for a decision a person made.

  • decide_timeTimestamp
Verification
{
"evidence": [
{
"kind": "KIND_STORE_UNAVAILABLE",
"url": "",
"quote": "",
"detail": "",
"observed_time": "2026-10-04T12:00:00Z"
}
],
"summary": "",
"unknown_signals": [
""
],
"model": "",
"decided_by": "",
"reason": "",
"decide_time": "2026-10-04T12:00:00Z"
}

BeginPurchaseResponse

  • purchasestring

    An opaque handle to pass to CompletePurchase.

  • order_idstring

    The distributor's order id — for Steam, the m_ulOrderID the MicroTxnAuthorizationResponse_t callback will carry.

CompletePurchaseResponse

  • STATE_INITIATEDSTATE_AUTHORIZEDSTATE_CREDITEDSTATE_CANCELLEDSTATE_FAILEDSTATE_REVERSED
  • Show child attributes
    • fundedbool
    • balanceMoney

      Set only for FUNDING_VISIBILITY_EXACT_BALANCE.

    • runway_daysint64

      Whole days, for EXACT_BALANCE and RUNWAY.

      Optional, and absent means "no runway to show" — nothing was spent recently to project from, or the visibility hides it. Zero means less than a day left. A plain integer could not tell those apart, and a game showing "0 days left" on a quiet, well-funded server would be telling its players something false and alarming.

    • FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
    • purchasablebool

      Whether a player can buy an offer right now, and why not if they cannot.

    • unavailable_reasonstring

Encore

Encore is an end-of-life game kept playable by its players.

  • gamestringRequiredImmutable

    The game, in the Game Registry: accounts/{account}/games/{game}.

  • distributor_linkstringRequiredImmutable

    The publisher link that sells this game.

  • listingListingRequiredImmutable

    The product on the link's storefront. Must be one of its listings.

    Show child attributes
    • distributorDistributorRequired
      DISTRIBUTOR_STEAM
    • product_idstringRequired

      The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

    • display_namestringOutput only

      The storefront's own name for it, when Plany has read one.

  • funding_visibilityFundingVisibilityRequired
    FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
  • namestringIdentifier
  • uidstringOutput only
  • display_namestring
  • encore_keystringOutput only

    The handle a game ships to name this Encore without a credential.

    Opaque and names no account: it is in every copy of the game, and what it unlocks is reading public funding and starting a purchase — both of which anybody who owns the game may do.

  • stateEncore.StateOutput only
    STATE_VERIFYINGSTATE_NEEDS_REVIEWSTATE_VERIFIEDSTATE_DECLINEDSTATE_REVOKED
  • verificationVerificationOutput only
    Show child attributes
    • Show child attributes
      • KIND_STORE_UNAVAILABLEKIND_OWNERSHIPKIND_ANNOUNCEMENTKIND_OPERATOR
      • urlstring

        Where it was found.

      • quotestring

        The words, verbatim, for an announcement. Checked against the post before it is recorded: a quote the model produced that is not in the post is discarded, never shown.

      • detailstring

        A sentence of context, e.g. the store's own availability text.

      • observed_timeTimestamp
    • summarystring

      Why the platform did or did not decide on its own, in a sentence.

    • unknown_signalsrepeated string

      Signals that could not be read, by name. A signal that could not be read is not a signal that fell short, and a reviewer needs to know which.

    • modelstring

      The model that read the announcements, when one did.

    • decided_bystring

      encore.plany.cloud for an automatic decision, or the person at Plany who reviewed it.

    • reasonstring

      The reviewer's own sentence, for a decision a person made.

    • decide_timeTimestamp
  • projectstringOutput only

    The top-up-only project, once there is one.

  • transferTransferOutput only
    Show child attributes
    • MODE_CONVERTMODE_MOVE
    • STATE_RUNNINGSTATE_SUCCEEDEDSTATE_FAILED
    • source_projectstring
    • Show child attributes
      • typestring

        The resource type, e.g. playpute.plany.cloud/GameServer.

      • sourcestring
      • destinationstring
      • STATE_PENDINGSTATE_RUNNINGSTATE_SUCCEEDEDSTATE_FAILEDSTATE_NEEDS_ACKNOWLEDGEMENT
      • messagestring
      • client_facingbool

        Something a shipped game client may address by name. Moving it changes that name, so a client nobody can patch stops reaching it.

    • messagestring
    • start_timeTimestamp
    • end_timeTimestamp
  • create_timeTimestampOutput only
  • update_timeTimestampOutput only
  • etagstring

Funding

Funding is a project's money, as its developer sees it.

  • encorestring
  • projectstring
  • balanceMoney

    Negative after a refund of credit already spent.

  • recent_spendMoney
  • spend_windowDuration
  • runwayDuration

    How long the balance lasts at the recent rate. Unset when nothing was spent in the window, because "forever" is not a runway.

  • fundedbool
  • purchasesint64

    Player purchases credited and reversed over the window.

  • reversalsint64
  • purchasedMoney

ListDistributorLinksResponse

  • distributor_linksrepeated DistributorLink
    Show child attributes
    • distributorDistributorRequiredImmutable
      DISTRIBUTOR_STEAM
    • namestringIdentifier
    • uidstringOutput only
    • display_namestring
    • steamSteamCredentialOne of credential
      Show child attributes
      • publisher_keystringInput onlyRequired

        A Steamworks publisher Web API key with Microtransaction permission.

        Write-only. Sealed before it is stored and never returned by any call: it can refund every order the publisher has ever taken.

      • sandboxboolImmutable

        Use ISteamMicroTxnSandbox. Orders are not charged and credit nothing, which is the whole integration minus the money.

      • publisher_key_fingerprintstringOutput only

        A fingerprint of the key, so a rotation can be seen to have happened: the first 16 hexadecimal characters of the SHA-256 of the key as sent. A client holding a key can compute it and compare without the key ever being read back.

    • stateDistributorLink.StateOutput only
      STATE_ACTIVESTATE_CREDENTIAL_INVALID
    • state_messagestringOutput only
    • listingsrepeated ListingOutput only

      Every product this credential can act for.

      Discovered from the distributor rather than declared — for Steam, ISteamApps/GetPartnerAppListForWebAPIKey — and that discovery is the proof a developer owns a game. An Encore can only name a listing here.

      Show child attributes
      • distributorDistributorRequired
        DISTRIBUTOR_STEAM
      • product_idstringRequired

        The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

      • display_namestringOutput only

        The storefront's own name for it, when Plany has read one.

    • outstandingMoneyOutput only

      Credit Plany has issued against this link and not been settled for.

    • reservedMoneyOutput only

      Credit held for purchases a player has started and not finished. Counted against the limit, so two players cannot both take the last of it.

    • outstanding_limitMoneyOutput only

      The most unsettled credit this link may carry. Set by Plany.

    • create_timeTimestampOutput only
    • update_timeTimestampOutput only
    • etagstringOutput only
    • distributor_share_basis_pointsint32Output only

      The distributor's share of a sale, out of 10,000. An offer's credit may be at most its price less this, which is how a form can show the largest credit allowed before anybody submits one.

  • next_page_tokenstring

ListEncoresResponse

  • Show child attributes
    • gamestringRequiredImmutable

      The game, in the Game Registry: accounts/{account}/games/{game}.

    • distributor_linkstringRequiredImmutable

      The publisher link that sells this game.

    • listingListingRequiredImmutable

      The product on the link's storefront. Must be one of its listings.

      Show child attributes
      • distributorDistributorRequired
        DISTRIBUTOR_STEAM
      • product_idstringRequired

        The product in the distributor's own terms. For Steam, the app id in decimal — a string because an id is not a quantity, and because a 64-bit number does not survive a JavaScript client.

      • display_namestringOutput only

        The storefront's own name for it, when Plany has read one.

    • funding_visibilityFundingVisibilityRequired
      FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
    • namestringIdentifier
    • uidstringOutput only
    • display_namestring
    • encore_keystringOutput only

      The handle a game ships to name this Encore without a credential.

      Opaque and names no account: it is in every copy of the game, and what it unlocks is reading public funding and starting a purchase — both of which anybody who owns the game may do.

    • stateEncore.StateOutput only
      STATE_VERIFYINGSTATE_NEEDS_REVIEWSTATE_VERIFIEDSTATE_DECLINEDSTATE_REVOKED
    • verificationVerificationOutput only
      Show child attributes
      • summarystring

        Why the platform did or did not decide on its own, in a sentence.

      • unknown_signalsrepeated string

        Signals that could not be read, by name. A signal that could not be read is not a signal that fell short, and a reviewer needs to know which.

      • modelstring

        The model that read the announcements, when one did.

      • decided_bystring

        encore.plany.cloud for an automatic decision, or the person at Plany who reviewed it.

      • reasonstring

        The reviewer's own sentence, for a decision a person made.

      • decide_timeTimestamp
    • projectstringOutput only

      The top-up-only project, once there is one.

    • transferTransferOutput only
      Show child attributes
    • create_timeTimestampOutput only
    • update_timeTimestampOutput only
    • etagstring
  • next_page_tokenstring

ListOffersResponse

  • Show child attributes
    • display_namestringRequired

      Shown in the Steam overlay when a player confirms a purchase.

    • priceMoneyRequired

      What the player pays, in USD. Steam converts to the player's own currency.

    • creditMoneyRequired

      What the project is credited, in USD.

      At most the price less the distributor's share. The developer is paid the net and owes Plany the credit, so a credit above the net is a developer owing more than they received on every sale.

    • namestringIdentifier
    • descriptionstring
    • activebool

      Whether players can buy it now. Every offer is created active; deactivate one with UpdateOffer.

    • item_idint64Output only

      The item id sent to the distributor. Stable for the offer's life.

    • create_timeTimestampOutput only
    • update_timeTimestampOutput only
  • next_page_tokenstring

ListPublicOffersResponse

  • Show child attributes
    • offer_idstring

      The offer's own id, to pass to BeginPurchase.

    • display_namestring
    • descriptionstring
    • priceMoney
  • purchasablebool
  • unavailable_reasonstring

ListPurchasesResponse

  • Show child attributes
    • namestringIdentifier
    • offerstring
    • order_idstring

      The distributor's order id. Decimal, for the reason Listing.product_id is.

    • player_idstring

      The player, in the distributor's terms: a SteamID64.

    • priceMoney
    • creditMoney
    • STATE_INITIATEDSTATE_AUTHORIZEDSTATE_CREDITEDSTATE_CANCELLEDSTATE_FAILEDSTATE_REVERSED
    • state_messagestring
    • ledger_entrystring

      The billing ledger entry that credited the project.

    • sandboxbool

      Whether this was a sandbox order, which credits nothing.

    • create_timeTimestamp
    • credit_timeTimestamp
    • reverse_timeTimestamp
  • next_page_tokenstring

ListSettlementsResponse

  • Show child attributes
    • namestringIdentifier
    • amountMoney
    • notestring
    • recorded_bystring
    • create_timeTimestamp
  • next_page_tokenstring

Offer

Offer is something a player can buy to fund the servers.

  • display_namestringRequired

    Shown in the Steam overlay when a player confirms a purchase.

  • priceMoneyRequired

    What the player pays, in USD. Steam converts to the player's own currency.

  • creditMoneyRequired

    What the project is credited, in USD.

    At most the price less the distributor's share. The developer is paid the net and owes Plany the credit, so a credit above the net is a developer owing more than they received on every sale.

  • namestringIdentifier
  • descriptionstring
  • activebool

    Whether players can buy it now. Every offer is created active; deactivate one with UpdateOffer.

  • item_idint64Output only

    The item id sent to the distributor. Stable for the offer's life.

  • create_timeTimestampOutput only
  • update_timeTimestampOutput only

PublicFunding

PublicFunding is what a game may show its players.

  • fundedbool
  • balanceMoney

    Set only for FUNDING_VISIBILITY_EXACT_BALANCE.

  • runway_daysint64

    Whole days, for EXACT_BALANCE and RUNWAY.

    Optional, and absent means "no runway to show" — nothing was spent recently to project from, or the visibility hides it. Zero means less than a day left. A plain integer could not tell those apart, and a game showing "0 days left" on a quiet, well-funded server would be telling its players something false and alarming.

  • FUNDING_VISIBILITY_EXACT_BALANCEFUNDING_VISIBILITY_RUNWAYFUNDING_VISIBILITY_FUNDED_FLAG
  • purchasablebool

    Whether a player can buy an offer right now, and why not if they cannot.

  • unavailable_reasonstring

Purchase

Purchase is one player's order.

  • namestringIdentifier
  • offerstring
  • order_idstring

    The distributor's order id. Decimal, for the reason Listing.product_id is.

  • player_idstring

    The player, in the distributor's terms: a SteamID64.

  • priceMoney
  • creditMoney
  • STATE_INITIATEDSTATE_AUTHORIZEDSTATE_CREDITEDSTATE_CANCELLEDSTATE_FAILEDSTATE_REVERSED
  • state_messagestring
  • ledger_entrystring

    The billing ledger entry that credited the project.

  • sandboxbool

    Whether this was a sandbox order, which credits nothing.

  • create_timeTimestamp
  • credit_timeTimestamp
  • reverse_timeTimestamp

TransferPlan

  • Show child attributes
    • typestring

      e.g. playpute.plany.cloud/GameServer.

    • namestring
    • display_namestring
    • locationstring
    • belongs_to_gamebool

      Found through the game itself, rather than only by being in the project.

    • client_facingbool

      A shipped game client may address it by name.

    • movablebool

      Whether a move of this type is supported. A candidate that is not is listed so the plan can say why CONVERT is not available, never silently left behind.

    • notestring
  • recommended_modeTransfer.Mode

    CONVERT when every billable resource in the project belongs to the game.

    MODE_CONVERTMODE_MOVE
  • explanationstring

    Why, in a sentence.

  • warningsrepeated string

    What a MOVE would cost the game's players, stated up front: that addresses change, that names in shipped clients stop resolving, that a hibernated server's memory is not carried.

Enums

Distributor

Distributor is a storefront a game is sold through.

ValueDescription
DISTRIBUTOR_UNSPECIFIED
DISTRIBUTOR_STEAMValve's Steam. Product ids are app ids.

DistributorLink.State

State of the credential, as last checked against the distributor.

ValueDescription
STATE_UNSPECIFIED
STATE_ACTIVEThe key works and owns at least one product.
STATE_CREDENTIAL_INVALIDThe distributor refused the key. Nothing using it can sell.

Encore.State

Whether the game has been confirmed as end of life.

ValueDescription
STATE_UNSPECIFIED
STATE_VERIFYINGPlany is gathering evidence.
STATE_NEEDS_REVIEWThe platform could not decide on its own, and a person will.
STATE_VERIFIEDConfirmed. Players can fund the project.
STATE_DECLINEDA person at Plany declined, with a reason in `verification.reason`.
STATE_REVOKEDVerified once and withdrawn by a person — a game that turned out not to be ending after all. Player purchases stop; credit already bought stays.

Evidence.Kind

ValueDescription
KIND_UNSPECIFIED
KIND_STORE_UNAVAILABLEThe distributor's store no longer sells the product.
KIND_OWNERSHIPThe linked credential can act for the product.
KIND_ANNOUNCEMENTThe developer's own announcement says the game is ending.
KIND_OPERATORA person at Plany decided.

FundingVisibility

FundingVisibility is how much of a project's funding a game may show players.

Required, with no working zero value. A studio may reasonably want players to see "37 days of servers left" and not want the exact balance of a project on their account published to anybody with the game; guessing either way publishes something nobody decided to.

ValueDescription
FUNDING_VISIBILITY_UNSPECIFIED
FUNDING_VISIBILITY_EXACT_BALANCEThe balance and the runway.
FUNDING_VISIBILITY_RUNWAYThe runway only, in whole days.
FUNDING_VISIBILITY_FUNDED_FLAGWhether the servers are funded, and nothing else.

Purchase.State

ValueDescription
STATE_UNSPECIFIED
STATE_INITIATEDOpened with the distributor; the player has not answered.
STATE_AUTHORIZEDThe player approved in the overlay; the order is being settled.
STATE_CREDITEDSettled, and the project credited.
STATE_CANCELLEDThe player declined, or never answered.
STATE_FAILEDThe distributor refused the order.
STATE_REVERSEDRefunded or charged back after being credited, and the credit taken back.

Transfer.Mode

ValueDescription
MODE_UNSPECIFIED
MODE_CONVERTThe source project already holds only this game, and becomes the Encore project. Nothing moves and no address changes.
MODE_MOVEA new project is created and each selected resource is moved into it.

Transfer.State

ValueDescription
STATE_UNSPECIFIED
STATE_RUNNING
STATE_SUCCEEDED
STATE_FAILED

TransferItem.State

ValueDescription
STATE_UNSPECIFIED
STATE_PENDING
STATE_RUNNING
STATE_SUCCEEDED
STATE_FAILED
STATE_NEEDS_ACKNOWLEDGEMENTWaiting for somebody to accept something the move cannot preserve — a stopped server whose disk is gone and can only move as a fresh install.