[GH-ISSUE #75] Add App Pricing & Availability management #19

Closed
opened 2026-02-26 21:32:49 +03:00 by kerem · 2 comments
Owner

Originally created by @rudrankriyam on GitHub (Jan 24, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/75

Summary

Add App Pricing & Availability management (price points, schedules, territories). ASC currently has no app pricing or availability tooling.

Current State (verified)

Repo search for app price schedules, price points, territories, app availability returns no matches.

API Endpoints (App Store Connect OpenAPI)

  • POST /v1/appPriceSchedules

  • GET /v1/appPriceSchedules/{id}

  • GET /v1/appPriceSchedules/{id}/automaticPrices

  • GET /v1/appPriceSchedules/{id}/manualPrices

  • GET /v1/appPriceSchedules/{id}/baseTerritory

  • GET /v1/apps/{id}/appPricePoints

  • GET /v3/appPricePoints/{id}

  • GET /v3/appPricePoints/{id}/equalizations

  • GET /v1/territories

Availability (v2)

  • POST /v2/appAvailabilities
  • GET /v2/appAvailabilities/{id}
  • GET /v2/appAvailabilities/{id}/territoryAvailabilities
  • GET /v1/apps/{id}/appAvailabilityV2

Proposed CLI

asc pricing territories list
asc pricing price-points --app APP_ID [--territory TERRITORY_ID]
asc pricing schedule create --app APP_ID --price-point PRICE_POINT_ID --start-date YYYY-MM-DD
asc pricing schedule get --id SCHEDULE_ID

asc availability get --app APP_ID
asc availability set --app APP_ID --territory TERRITORY_ID[,TERRITORY_ID...] --available true|false

Implementation Plan

  1. internal/asc/pricing.go
  • Types for price points, price schedules, territories, availability.
  • Client methods for list/get/create.
  1. cmd/pricing.go
  • New pricing command group and availability subcommands.
  • Validation for IDs and dates.
  1. Output helpers
  • Table/markdown for territories and price points.
  1. Tests
  • CLI validation + HTTP client tests.

Acceptance Criteria

  • Can list territories and price points for an app.
  • Can create and read price schedules.
  • Can read and update app availability.
  • JSON output by default; table/markdown supported.
Originally created by @rudrankriyam on GitHub (Jan 24, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/75 ## Summary Add App Pricing & Availability management (price points, schedules, territories). ASC currently has no app pricing or availability tooling. ## Current State (verified) Repo search for app price schedules, price points, territories, app availability returns no matches. ## API Endpoints (App Store Connect OpenAPI) - `POST /v1/appPriceSchedules` - `GET /v1/appPriceSchedules/{id}` - `GET /v1/appPriceSchedules/{id}/automaticPrices` - `GET /v1/appPriceSchedules/{id}/manualPrices` - `GET /v1/appPriceSchedules/{id}/baseTerritory` - `GET /v1/apps/{id}/appPricePoints` - `GET /v3/appPricePoints/{id}` - `GET /v3/appPricePoints/{id}/equalizations` - `GET /v1/territories` Availability (v2) - `POST /v2/appAvailabilities` - `GET /v2/appAvailabilities/{id}` - `GET /v2/appAvailabilities/{id}/territoryAvailabilities` - `GET /v1/apps/{id}/appAvailabilityV2` ## Proposed CLI ``` asc pricing territories list asc pricing price-points --app APP_ID [--territory TERRITORY_ID] asc pricing schedule create --app APP_ID --price-point PRICE_POINT_ID --start-date YYYY-MM-DD asc pricing schedule get --id SCHEDULE_ID asc availability get --app APP_ID asc availability set --app APP_ID --territory TERRITORY_ID[,TERRITORY_ID...] --available true|false ``` ## Implementation Plan 1) `internal/asc/pricing.go` - Types for price points, price schedules, territories, availability. - Client methods for list/get/create. 2) `cmd/pricing.go` - New `pricing` command group and `availability` subcommands. - Validation for IDs and dates. 3) Output helpers - Table/markdown for territories and price points. 4) Tests - CLI validation + HTTP client tests. ## Acceptance Criteria - Can list territories and price points for an app. - Can create and read price schedules. - Can read and update app availability. - JSON output by default; table/markdown supported.
kerem closed this issue 2026-02-26 21:32:49 +03:00
Author
Owner

@rudrankriyam commented on GitHub (Jan 24, 2026):

@cursor

Implementation Guide

Codebase Context

This feature covers App Pricing and Availability - price schedules, price points, territories, and app availability management.

File Structure

1. internal/asc/pricing.go (~200-250 lines)

// Territory types
type TerritoryAttributes struct {
    Currency string `json:"currency"`
}

// Price Point types (v3)
type AppPricePointV3Attributes struct {
    CustomerPrice string `json:"customerPrice"`
    Proceeds      string `json:"proceeds"`
}

// Price Schedule types
type AppPriceScheduleAttributes struct {
    // Usually empty - data in relationships
}

type AppPriceAttributes struct {
    StartDate   string `json:"startDate,omitempty"`
    EndDate     string `json:"endDate,omitempty"`
    Manual      bool   `json:"manual,omitempty"`
}

// Availability types (v2)
type AppAvailabilityV2Attributes struct {
    AvailableInNewTerritories bool `json:"availableInNewTerritories"`
}

type TerritoryAvailabilityAttributes struct {
    Available       bool   `json:"available"`
    ReleaseDate     string `json:"releaseDate,omitempty"`
    PreOrderEnabled bool   `json:"preOrderEnabled,omitempty"`
}

// Response types
type TerritoriesResponse = Response[TerritoryAttributes]
type AppPricePointsV3Response = Response[AppPricePointV3Attributes]
type AppPriceScheduleResponse = SingleResponse[AppPriceScheduleAttributes]
type AppAvailabilityV2Response = SingleResponse[AppAvailabilityV2Attributes]
type TerritoryAvailabilitiesResponse = Response[TerritoryAvailabilityAttributes]

2. internal/asc/client_pricing.go (~150-200 lines)

// Territories
func (c *Client) GetTerritories(ctx context.Context, opts ...TerritoriesOption) (*TerritoriesResponse, error)

// Price Points (v3 - preferred)
func (c *Client) GetAppPricePoints(ctx context.Context, appID string, opts ...PricePointsOption) (*AppPricePointsV3Response, error)
func (c *Client) GetAppPricePoint(ctx context.Context, pricePointID string) (*AppPricePointV3Response, error)
func (c *Client) GetAppPricePointEqualizations(ctx context.Context, pricePointID string) (*AppPricePointsV3Response, error)

// Price Schedule
func (c *Client) GetAppPriceSchedule(ctx context.Context, appID string) (*AppPriceScheduleResponse, error)
func (c *Client) CreateAppPriceSchedule(ctx context.Context, appID string, attrs AppPriceScheduleCreateAttributes) (*AppPriceScheduleResponse, error)
func (c *Client) GetAppPriceScheduleManualPrices(ctx context.Context, scheduleID string) (*AppPricesResponse, error)
func (c *Client) GetAppPriceScheduleAutomaticPrices(ctx context.Context, scheduleID string) (*AppPricesResponse, error)

// Availability (v2)
func (c *Client) GetAppAvailabilityV2(ctx context.Context, appID string) (*AppAvailabilityV2Response, error)
func (c *Client) CreateAppAvailabilityV2(ctx context.Context, appID string, attrs AppAvailabilityV2CreateAttributes) (*AppAvailabilityV2Response, error)
func (c *Client) GetTerritoryAvailabilities(ctx context.Context, availabilityID string) (*TerritoryAvailabilitiesResponse, error)

3. internal/asc/pricing_output.go (~100-150 lines)

func printTerritoriesTable(resp *TerritoriesResponse) error
func printTerritoriesMarkdown(resp *TerritoriesResponse) error
func printAppPricePointsTable(resp *AppPricePointsV3Response) error
func printAppPricePointsMarkdown(resp *AppPricePointsV3Response) error
func printAppAvailabilityTable(resp *AppAvailabilityV2Response) error
func printAppAvailabilityMarkdown(resp *AppAvailabilityV2Response) error

4. cmd/pricing.go (~300-350 lines)

func PricingCommand() *ffcli.Command  // Parent

// Subcommands
func PricingTerritoriesCommand() *ffcli.Command   // list all territories
func PricingPricePointsCommand() *ffcli.Command   // --app APP_ID [--territory]
func PricingScheduleCommand() *ffcli.Command      // Nested group
func PricingScheduleGetCommand() *ffcli.Command   // --app APP_ID
func PricingScheduleCreateCommand() *ffcli.Command // --app --price-point --start-date

func PricingAvailabilityCommand() *ffcli.Command  // Nested group  
func PricingAvailabilityGetCommand() *ffcli.Command    // --app APP_ID
func PricingAvailabilitySetCommand() *ffcli.Command    // --app --territory --available true|false

5. Register in cmd/commands.go
Add PricingCommand() to RootCommand().Subcommands

API Endpoints Reference

Territories:
GET    /v1/territories                                   → GetTerritories

Price Points (v3):
GET    /v1/apps/{id}/appPricePoints                      → GetAppPricePoints
GET    /v3/appPricePoints/{id}                           → GetAppPricePoint
GET    /v3/appPricePoints/{id}/equalizations             → GetAppPricePointEqualizations

Price Schedule:
GET    /v1/apps/{id}/appPriceSchedule                    → GetAppPriceSchedule (via relationship)
POST   /v1/appPriceSchedules                             → CreateAppPriceSchedule
GET    /v1/appPriceSchedules/{id}                        → GetAppPriceSchedule
GET    /v1/appPriceSchedules/{id}/manualPrices           → GetAppPriceScheduleManualPrices
GET    /v1/appPriceSchedules/{id}/automaticPrices        → GetAppPriceScheduleAutomaticPrices
GET    /v1/appPriceSchedules/{id}/baseTerritory          → GetAppPriceScheduleBaseTerritory

Availability (v2):
GET    /v1/apps/{id}/appAvailabilityV2                   → GetAppAvailabilityV2 (via relationship)
POST   /v2/appAvailabilities                             → CreateAppAvailabilityV2
GET    /v2/appAvailabilities/{id}                        → GetAppAvailabilityV2
GET    /v2/appAvailabilities/{id}/territoryAvailabilities → GetTerritoryAvailabilities

CLI Usage Examples

# List all territories
asc pricing territories list

# Get price points for an app
asc pricing price-points --app "123456789"
asc pricing price-points --app "123456789" --territory "USA"

# Get price schedule
asc pricing schedule get --app "123456789"

# Create price schedule
asc pricing schedule create --app "123456789" --price-point "PRICE_POINT_ID" --start-date "2024-03-01"

# Get availability
asc pricing availability get --app "123456789"

# Set availability for territories
asc pricing availability set --app "123456789" --territory "USA,GBR,DEU" --available true

Testing

  • Run make test && make lint
  • Test territory list pagination
  • Test date format validation for schedule creation
<!-- gh-comment-id:3795328792 --> @rudrankriyam commented on GitHub (Jan 24, 2026): @cursor ## Implementation Guide ### Codebase Context This feature covers App Pricing and Availability - price schedules, price points, territories, and app availability management. ### File Structure **1. `internal/asc/pricing.go`** (~200-250 lines) ```go // Territory types type TerritoryAttributes struct { Currency string `json:"currency"` } // Price Point types (v3) type AppPricePointV3Attributes struct { CustomerPrice string `json:"customerPrice"` Proceeds string `json:"proceeds"` } // Price Schedule types type AppPriceScheduleAttributes struct { // Usually empty - data in relationships } type AppPriceAttributes struct { StartDate string `json:"startDate,omitempty"` EndDate string `json:"endDate,omitempty"` Manual bool `json:"manual,omitempty"` } // Availability types (v2) type AppAvailabilityV2Attributes struct { AvailableInNewTerritories bool `json:"availableInNewTerritories"` } type TerritoryAvailabilityAttributes struct { Available bool `json:"available"` ReleaseDate string `json:"releaseDate,omitempty"` PreOrderEnabled bool `json:"preOrderEnabled,omitempty"` } // Response types type TerritoriesResponse = Response[TerritoryAttributes] type AppPricePointsV3Response = Response[AppPricePointV3Attributes] type AppPriceScheduleResponse = SingleResponse[AppPriceScheduleAttributes] type AppAvailabilityV2Response = SingleResponse[AppAvailabilityV2Attributes] type TerritoryAvailabilitiesResponse = Response[TerritoryAvailabilityAttributes] ``` **2. `internal/asc/client_pricing.go`** (~150-200 lines) ```go // Territories func (c *Client) GetTerritories(ctx context.Context, opts ...TerritoriesOption) (*TerritoriesResponse, error) // Price Points (v3 - preferred) func (c *Client) GetAppPricePoints(ctx context.Context, appID string, opts ...PricePointsOption) (*AppPricePointsV3Response, error) func (c *Client) GetAppPricePoint(ctx context.Context, pricePointID string) (*AppPricePointV3Response, error) func (c *Client) GetAppPricePointEqualizations(ctx context.Context, pricePointID string) (*AppPricePointsV3Response, error) // Price Schedule func (c *Client) GetAppPriceSchedule(ctx context.Context, appID string) (*AppPriceScheduleResponse, error) func (c *Client) CreateAppPriceSchedule(ctx context.Context, appID string, attrs AppPriceScheduleCreateAttributes) (*AppPriceScheduleResponse, error) func (c *Client) GetAppPriceScheduleManualPrices(ctx context.Context, scheduleID string) (*AppPricesResponse, error) func (c *Client) GetAppPriceScheduleAutomaticPrices(ctx context.Context, scheduleID string) (*AppPricesResponse, error) // Availability (v2) func (c *Client) GetAppAvailabilityV2(ctx context.Context, appID string) (*AppAvailabilityV2Response, error) func (c *Client) CreateAppAvailabilityV2(ctx context.Context, appID string, attrs AppAvailabilityV2CreateAttributes) (*AppAvailabilityV2Response, error) func (c *Client) GetTerritoryAvailabilities(ctx context.Context, availabilityID string) (*TerritoryAvailabilitiesResponse, error) ``` **3. `internal/asc/pricing_output.go`** (~100-150 lines) ```go func printTerritoriesTable(resp *TerritoriesResponse) error func printTerritoriesMarkdown(resp *TerritoriesResponse) error func printAppPricePointsTable(resp *AppPricePointsV3Response) error func printAppPricePointsMarkdown(resp *AppPricePointsV3Response) error func printAppAvailabilityTable(resp *AppAvailabilityV2Response) error func printAppAvailabilityMarkdown(resp *AppAvailabilityV2Response) error ``` **4. `cmd/pricing.go`** (~300-350 lines) ```go func PricingCommand() *ffcli.Command // Parent // Subcommands func PricingTerritoriesCommand() *ffcli.Command // list all territories func PricingPricePointsCommand() *ffcli.Command // --app APP_ID [--territory] func PricingScheduleCommand() *ffcli.Command // Nested group func PricingScheduleGetCommand() *ffcli.Command // --app APP_ID func PricingScheduleCreateCommand() *ffcli.Command // --app --price-point --start-date func PricingAvailabilityCommand() *ffcli.Command // Nested group func PricingAvailabilityGetCommand() *ffcli.Command // --app APP_ID func PricingAvailabilitySetCommand() *ffcli.Command // --app --territory --available true|false ``` **5. Register in `cmd/commands.go`** Add `PricingCommand()` to RootCommand().Subcommands ### API Endpoints Reference ``` Territories: GET /v1/territories → GetTerritories Price Points (v3): GET /v1/apps/{id}/appPricePoints → GetAppPricePoints GET /v3/appPricePoints/{id} → GetAppPricePoint GET /v3/appPricePoints/{id}/equalizations → GetAppPricePointEqualizations Price Schedule: GET /v1/apps/{id}/appPriceSchedule → GetAppPriceSchedule (via relationship) POST /v1/appPriceSchedules → CreateAppPriceSchedule GET /v1/appPriceSchedules/{id} → GetAppPriceSchedule GET /v1/appPriceSchedules/{id}/manualPrices → GetAppPriceScheduleManualPrices GET /v1/appPriceSchedules/{id}/automaticPrices → GetAppPriceScheduleAutomaticPrices GET /v1/appPriceSchedules/{id}/baseTerritory → GetAppPriceScheduleBaseTerritory Availability (v2): GET /v1/apps/{id}/appAvailabilityV2 → GetAppAvailabilityV2 (via relationship) POST /v2/appAvailabilities → CreateAppAvailabilityV2 GET /v2/appAvailabilities/{id} → GetAppAvailabilityV2 GET /v2/appAvailabilities/{id}/territoryAvailabilities → GetTerritoryAvailabilities ``` ### CLI Usage Examples ```bash # List all territories asc pricing territories list # Get price points for an app asc pricing price-points --app "123456789" asc pricing price-points --app "123456789" --territory "USA" # Get price schedule asc pricing schedule get --app "123456789" # Create price schedule asc pricing schedule create --app "123456789" --price-point "PRICE_POINT_ID" --start-date "2024-03-01" # Get availability asc pricing availability get --app "123456789" # Set availability for territories asc pricing availability set --app "123456789" --territory "USA,GBR,DEU" --available true ``` ### Testing - Run `make test && make lint` - Test territory list pagination - Test date format validation for schedule creation
Author
Owner

@cursor[bot] commented on GitHub (Jan 24, 2026):

Summary:

  • Added pricing/availability types, client endpoints, pagination support, and table/markdown output helpers.
  • Implemented asc pricing CLI with territories, price points, schedule, and availability subcommands plus validations.
  • Added client and CLI validation tests for pricing/availability, including pagination coverage.

Tests:

  • make test
  • make lint

View PR
Open in Cursor Open in Web

<!-- gh-comment-id:3795328849 --> @cursor[bot] commented on GitHub (Jan 24, 2026): Summary: - Added pricing/availability types, client endpoints, pagination support, and table/markdown output helpers. - Implemented `asc pricing` CLI with territories, price points, schedule, and availability subcommands plus validations. - Added client and CLI validation tests for pricing/availability, including pagination coverage. Tests: - `make test` - `make lint` <a href="https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/105"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/view-pr-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/view-pr-light.svg"><img alt="View PR" src="https://cursor.com/view-pr-light.svg"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-26358d8b-278f-4eb3-9d54-66b14485fb53"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-cursor-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in Cursor" src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a href="https://cursor.com/agents?id=bc-26358d8b-278f-4eb3-9d54-66b14485fb53"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/open-in-web-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web" src="https://cursor.com/open-in-web.svg"></picture></a>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#19
No description provided.