Skip to content

Creating ASO Projects - Complete Guide

This guide walks you through creating a complete ASO (App Store Optimization) project from start to finish in just 2 API calls.

Prerequisites

Before you start, you'll need:

  1. JWT Authentication Token - Get from /api/auth/google/ or /api/token/refresh/
  2. Workspace ID - Get from GET /api/workspaces/
  3. Project ID - Create via POST /api/workspaces/{workspace_id}/projects/

See Authentication Guide for details on getting your JWT token.


Quick Start (2 Steps)

Step 1: Create Base Project (1 API Call)

# Set your variables
WORKSPACE_ID="your-workspace-uuid"
JWT_TOKEN="your-jwt-token"

# Create the project
curl -X POST "http://localhost:8000/api/workspaces/${WORKSPACE_ID}/projects/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "WhatsApp Android - US Market",
    "type": "ASO_ANDROID"
  }'

Response (201 Created):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "WhatsApp Android - US Market",
  "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
  "type": "ASO_ANDROID",
  "user_access": [],
  "aso_android_config": null,
  "created_at": "2024-10-28T12:00:00Z"
}

Save the project ID - you'll need it next!


Step 2: Configure ASO Project (1 API Call)

This single request creates everything: app, markets, keywords, and ASO configuration.

PROJECT_ID="550e8400-e29b-41d4-a716-446655440000"  # From Step 1

curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app": {
      "name": "WhatsApp Messenger",
      "package_id": "com.whatsapp"
    },
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": [
          "messaging app",
          "secure messenger",
          "whatsapp",
          "encrypted messages"
        ],
        "competitors": []
      }
    ],
    "notes": "WhatsApp US market tracker"
  }'

Response (201 Created):

{
  "id": "bb0e8400-e29b-41d4-a716-446655440006",
  "app": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "WhatsApp Messenger",
    "package_id": "com.whatsapp"
  },
  "markets": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "country": "us",
      "language": "en"
    }
  ],
  "keywords": [
    {"id": "880e8400-e29b-41d4-a716-446655440003", "text": "messaging app"},
    {"id": "990e8400-e29b-41d4-a716-446655440004", "text": "secure messenger"},
    {"id": "990e8400-e29b-41d4-a716-446655440005", "text": "whatsapp"},
    {"id": "990e8400-e29b-41d4-a716-446655440006", "text": "encrypted messages"}
  ],
  "competitors": [],
  "notes": "WhatsApp US market tracker"
}

Done! Your ASO project is ready for tracking! ✅


Complete Examples

Example 1: Android - WhatsApp (New App)

Create a complete Android project with a new app:

curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app": {
      "name": "WhatsApp Messenger",
      "package_id": "com.whatsapp"
    },
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": [
          "messaging app",
          "secure messenger",
          "whatsapp",
          "private chat",
          "encrypted messages"
        ],
        "competitors": []
      }
    ],
    "notes": "WhatsApp US market tracker"
  }'

Example 2: Android - Telegram (Existing App)

Create a project using an existing app (by app_id):

# If WhatsApp app already exists, reference it by ID
curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "550e8400-e29b-41d4-a716-446655440000",
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": [
          "messaging app",
          "telegram app",
          "encrypted messenger"
        ],
        "competitors": []
      }
    ],
    "notes": "Telegram US market"
  }'

Example 3: Apple iOS - WhatsApp

Create an iOS app project:

# First create base project with type ASO_APPLE
curl -X POST "http://localhost:8000/api/workspaces/${WORKSPACE_ID}/projects/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "WhatsApp iOS - US Market",
    "type": "ASO_APPLE"
  }'

# Response includes project_id, then configure it:
PROJECT_ID="550e8400-e29b-41d4-a716-446655440001"

curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/apple/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app": {
      "name": "WhatsApp Messenger",
      "bundle_id": "net.whatsapp.WhatsApp"
    },
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": [
          "messaging app",
          "secure messenger",
          "whatsapp"
        ],
        "competitors": []
      }
    ],
    "notes": "WhatsApp iOS US market"
  }'

Example 4: Multiple Markets (Same App)

Track the same app across multiple markets in ONE request:

# Single project tracking WhatsApp across three markets
curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app": {
      "name": "WhatsApp Messenger",
      "package_id": "com.whatsapp"
    },
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": ["messaging app", "secure messenger", "whatsapp"]
      },
      {
        "country": "de",
        "language": "de",
        "keywords": ["Messaging-App", "sicherer Messenger", "whatsapp"]
      },
      {
        "country": "jp",
        "language": "ja",
        "keywords": ["メッセージングアプリ", "安全なメッセンジャー"]
      }
    ],
    "notes": "WhatsApp multi-market tracker - US, DE, JP"
  }'

Result: One project tracking WhatsApp in all three markets with language-specific keywords!

Note: If you need to track the same app with completely different configurations (separate keywords per market), create separate projects for each market and use app_id to reference the same app.


Example 5: With Competitors

Track competitors in the same market:

curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "app": {
      "name": "WhatsApp Messenger",
      "package_id": "com.whatsapp"
    },
    "markets": [
      {
        "country": "us",
        "language": "en",
        "keywords": [
          "messaging app",
          "secure messenger",
          "encrypted chat"
        ],
        "competitors": [
          {
            "package_id": "org.telegram.messenger",
            "country": "us",
            "language": "en"
          },
          {
            "package_id": "org.signal.android",
            "country": "us",
            "language": "en"
          }
        ]
      }
    ],
    "notes": "Track WhatsApp vs Telegram and Signal in US"
  }'

Request Fields Reference

app (optional)

Create a new app with these fields:

Field Type Required Example
name string "WhatsApp Messenger"
package_id (Android) string "com.whatsapp"
bundle_id (iOS) string "net.whatsapp.WhatsApp"

Either app or app_id is required (not both)

app_id (optional)

Use an existing app by UUID:

{
  "app_id": "550e8400-e29b-41d4-a716-446655440000"
}

markets (required)

List of markets to track for this app. Each market is a country-language pair with its own keywords and competitors.

{
  "markets": [
    {
      "country": "us",
      "language": "en",
      "keywords": ["messaging app", "secure messenger"],
      "competitors": []
    },
    {
      "country": "de",
      "language": "de",
      "keywords": ["Messaging-App"],
      "competitors": []
    }
  ]
}

Market Fields:

Field Type Required Example Notes
country string "us" ISO 2-letter code
language string "en" ISO language code
keywords array ["messaging app"] Keywords for this market
competitors array [{...}] Competitors in this market

Common Country Codes: - us - United States - gb - United Kingdom - de - Germany - fr - France - jp - Japan - in - India - br - Brazil - es - Spain - it - Italy - ca - Canada - au - Australia

keywords (within market)

List of keywords to track for each market:

{
  "keywords": [
    "messaging app",
    "secure messenger",
    "whatsapp",
    "encrypted messages"
  ]
}

Notes: - Keywords are automatically converted to lowercase - Can include any number of keywords - Optional - projects work without keywords - Keywords are specific to each market

competitors (within market)

List of competitor apps to monitor in each market:

{
  "competitors": [
    {
      "package_id": "org.telegram.messenger",
      "country": "us",
      "language": "en"
    },
    {
      "package_id": "org.signal.android",
      "country": "us",
      "language": "en"
    }
  ]
}

Competitor Fields:

Field Type Required Example Notes
package_id (Android) string "org.telegram.messenger" Competitor app ID
bundle_id (iOS) string "org.telegram.messenger" Competitor app ID
country string "us" Must match market country
language string "en" Must match market language

Notes: - Competitors must be in the SAME market (country+language) they're being monitored in - Both country and language required - Optional field

notes (optional)

Internal documentation:

{
  "notes": "Primary market tracker - Q4 campaign"
}

Common Android Package IDs

App Package ID
WhatsApp com.whatsapp
Telegram org.telegram.messenger
Signal org.signal.android
Instagram com.instagram.android
Facebook Messenger com.facebook.orca
Google Messages com.google.android.apps.messaging
Viber com.viber.voip
WeChat com.tencent.mm
Snapchat com.snapchat.android
Discord com.discord

Common Apple Bundle IDs

App Bundle ID
WhatsApp net.whatsapp.WhatsApp
Telegram org.telegram.messenger
Signal org.whispersystems.signal
Instagram com.burbn.instagram
Facebook Messenger com.facebook.Messenger
Google Messages com.google.android.apps.messaging
Viber com.viber.voip
WeChat com.tencent.wechat
Snapchat com.toyopagroup.picaboo
Discord com.hammerandchisel.discord

Error Handling

400 Bad Request

Missing required fields:

{
  "primary_acl": ["This field is required."]
}

Invalid app data:

{
  "app": ["'app' must contain 'name' and 'package_id' fields."]
}

Invalid project type:

{
  "error": "Project must be of type ASO_ANDROID"
}

Solution: Check your request body matches the required fields.

401 Unauthorized

{
  "detail": "Authentication credentials were not provided."
}

Solution: Add valid JWT token in Authorization header:

-H "Authorization: Bearer YOUR_JWT_TOKEN"

403 Forbidden

{
  "detail": "You do not have permission to perform this action."
}

Solution: Ensure you have access to the project's workspace.

404 Not Found

{
  "detail": "Not found."
}

Solution: Verify the project_id exists and is correct.


Tips & Best Practices

1. Reuse Apps When Possible

If you're tracking the same app in multiple markets, reuse it:

# First project (creates app)
curl -X POST ".../projects/proj-1/config/android/" ... \
  -d '{"app": {"name": "...", "package_id": "com.whatsapp"}}'

# Second project (reuses same app)
curl -X POST ".../projects/proj-2/config/android/" ... \
  -d '{"app_id": "app-uuid-from-first-response"}'

2. Organize by Market

Create separate projects for each market:

WhatsApp Project
├── WhatsApp - US/EN
├── WhatsApp - DE/DE
├── WhatsApp - JP/JA
└── WhatsApp - BR/PT

3. Use Meaningful Project Names

{
  "name": "WhatsApp - US Market Q4 2024"
}

4. Add Detailed Notes

{
  "notes": "Track messaging apps in US. Compare vs Telegram, Signal. Q4 campaign."
}

5. Start with Core Keywords

Don't over-engineer keywords. Start simple:

{
  "keywords": [
    "messaging app",
    "secure messenger",
    "app-name"
  ]
}

Then expand based on campaign needs.


Bash Script Template

Save this as create_project.sh for automated project creation:

#!/bin/bash

# Configuration
WORKSPACE_ID="${1:-YOUR_WORKSPACE_UUID}"
JWT_TOKEN="${2:-YOUR_JWT_TOKEN}"
APP_NAME="${3:-WhatsApp}"
PACKAGE_ID="${4:-com.whatsapp}"
COUNTRY="${5:-us}"
LANGUAGE="${6:-en}"

# Step 1: Create base project
echo "Creating base project..."
PROJECT_RESPONSE=$(curl -s -X POST "http://localhost:8000/api/workspaces/${WORKSPACE_ID}/projects/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"${APP_NAME} - ${COUNTRY}/${LANGUAGE}\",
    \"type\": \"ASO_ANDROID\"
  }")

PROJECT_ID=$(echo $PROJECT_RESPONSE | jq -r '.id')
echo "Created project: $PROJECT_ID"

# Step 2: Configure ASO project
echo "Configuring ASO project..."
curl -X POST "http://localhost:8000/api/projects/${PROJECT_ID}/config/android/" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"app\": {
      \"name\": \"${APP_NAME}\",
      \"package_id\": \"${PACKAGE_ID}\"
    },
    \"markets\": [
      {
        \"country\": \"${COUNTRY}\",
        \"language\": \"${LANGUAGE}\",
        \"keywords\": [
          \"messaging app\",
          \"secure messenger\"
        ],
        \"competitors\": []
      }
    ],
    \"notes\": \"${APP_NAME} tracking - ${COUNTRY}/${LANGUAGE}\"
  }"

echo "Done! Project ready for tracking."

Usage:

chmod +x create_project.sh
./create_project.sh workspace-uuid jwt-token "WhatsApp" "com.whatsapp" "us" "en"


Python Script Template

import requests
import json

def create_aso_project(workspace_id, jwt_token, app_name, package_id,
                       country="us", language="en", app_type="ASO_ANDROID"):
    """
    Create a complete ASO project in one call.

    Args:
        workspace_id: UUID of the workspace
        jwt_token: JWT authentication token
        app_name: Name of the app (e.g., "WhatsApp")
        package_id: Package ID (Android) or bundle_id (Apple)
        country: Country code (default: "us")
        language: Language code (default: "en")
        app_type: ASO_ANDROID or ASO_APPLE (default: ASO_ANDROID)
    """

    BASE_URL = "http://localhost:8000/api"
    headers = {
        "Authorization": f"Bearer {jwt_token}",
        "Content-Type": "application/json"
    }

    # Step 1: Create base project
    project_data = {
        "name": f"{app_name} - {country.upper()}/{language.upper()}",
        "type": app_type
    }

    response = requests.post(
        f"{BASE_URL}/workspaces/{workspace_id}/projects/",
        json=project_data,
        headers=headers
    )
    response.raise_for_status()
    project = response.json()
    project_id = project["id"]
    print(f"✓ Created project: {project_id}")

    # Step 2: Configure ASO project
    app_field = "package_id" if app_type == "ASO_ANDROID" else "bundle_id"

    config_data = {
        "app": {
            "name": app_name,
            app_field: package_id
        },
        "markets": [
            {
                "country": country,
                "language": language,
                "keywords": [
                    "messaging app",
                    "secure messenger"
                ],
                "competitors": []
            }
        ],
        "notes": f"{app_name} tracking - {country}/{language}"
    }

    config_endpoint = "config/android" if app_type == "ASO_ANDROID" else "config/apple"
    response = requests.post(
        f"{BASE_URL}/projects/{project_id}/{config_endpoint}/",
        json=config_data,
        headers=headers
    )
    response.raise_for_status()
    aso_config = response.json()
    print(f"✓ Created ASO configuration: {aso_config['id']}")

    return {
        "project_id": project_id,
        "aso_config_id": aso_config["id"],
        "app_id": aso_config["app"]["id"]
    }

# Usage:
if __name__ == "__main__":
    result = create_aso_project(
        workspace_id="660e8400-e29b-41d4-a716-446655440001",
        jwt_token="your-jwt-token",
        app_name="WhatsApp",
        package_id="com.whatsapp"
    )
    print(json.dumps(result, indent=2))


Next Steps

After creating your ASO project:

  1. View Project - GET /api/workspaces/{workspace_id}/projects/{project_id}/
  2. Update Project - PUT /api/workspaces/{workspace_id}/projects/{project_id}/
  3. Share Project - POST /api/workspaces/{workspace_id}/projects/{project_id}/share/
  4. Query Analytics - Use ClickHouse services (coming soon)
  5. Run Scraping - Trigger data collection (coming soon)

See the Workspaces Guide for project management endpoints.