Skip to content

Quick Start

This guide walks you through common operations with aha-go.

Prerequisites

Using the CLI

List Products

aha product list

List Features in a Product

aha feature list --product PRODUCT-KEY

Get Feature Details

aha feature get FEAT-123

Create a Feature

aha feature create --product PRODUCT-KEY \
  --name "New Feature" \
  --description "Feature description"

Output Formats

# JSON output
aha feature list --product PRODUCT-KEY --output json

# Table output (default)
aha feature list --product PRODUCT-KEY --output table

Using the Library

Basic Client Setup

package main

import (
    "context"
    "fmt"
    "log"

    aha "github.com/grokify/aha-go"
)

func main() {
    ctx := context.Background()

    // Create client from environment variables
    client, err := aha.NewClient()
    if err != nil {
        log.Fatal(err)
    }

    // List products
    products, err := client.ListProducts(ctx)
    if err != nil {
        log.Fatal(err)
    }

    for _, p := range products {
        fmt.Printf("%s: %s\n", p.ReferencePrefix, p.Name)
    }
}

Working with Features

// List features in a product
features, err := client.ListFeatures(ctx, "PRODUCT-KEY")
if err != nil {
    log.Fatal(err)
}

// Get a specific feature
feature, err := client.GetFeature(ctx, "FEAT-123")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Feature: %s - %s\n", feature.ReferenceNum, feature.Name)

// Create a feature
newFeature, err := client.CreateFeature(ctx, "PRODUCT-KEY", aha.CreateFeatureRequest{
    Name:        "New Feature",
    Description: "Description here",
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created: %s\n", newFeature.ReferenceNum)

// Update a feature
_, err = client.UpdateFeature(ctx, "FEAT-123", aha.UpdateFeatureRequest{
    Name: "Updated Feature Name",
})

Working with Ideas

// List ideas
ideas, err := client.ListIdeas(ctx, "PRODUCT-KEY")
if err != nil {
    log.Fatal(err)
}

// Get top voted ideas
for _, idea := range ideas {
    if idea.Votes >= 10 {
        fmt.Printf("%s: %s (%d votes)\n", idea.ReferenceNum, idea.Name, idea.Votes)
    }
}

Working with Releases

// List releases
releases, err := client.ListReleases(ctx, "PRODUCT-KEY")
if err != nil {
    log.Fatal(err)
}

// Find active releases
for _, r := range releases {
    if !r.Released {
        fmt.Printf("%s: %s (due: %s)\n", r.ReferenceNum, r.Name, r.ReleaseDate)
    }
}

Adding Comments

// Add a comment to a feature
comment, err := client.CreateComment(ctx, aha.CreateCommentRequest{
    CommentableType: "Feature",
    CommentableID:   "FEAT-123",
    Body:            "This is a comment from the API",
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Comment added: %s\n", comment.ID)

Error Handling

features, err := client.ListFeatures(ctx, "PRODUCT-KEY")
if err != nil {
    // Check for specific error types
    if aha.IsNotFoundError(err) {
        fmt.Println("Product not found")
    } else if aha.IsUnauthorizedError(err) {
        fmt.Println("Invalid API key")
    } else {
        fmt.Printf("Error: %v\n", err)
    }
    return
}

Pagination

For large result sets, use pagination options:

// Get first page
features, err := client.ListFeatures(ctx, "PRODUCT-KEY",
    aha.WithPage(1),
    aha.WithPerPage(50),
)

// Iterate through all pages
page := 1
for {
    features, err := client.ListFeatures(ctx, "PRODUCT-KEY",
        aha.WithPage(page),
        aha.WithPerPage(100),
    )
    if err != nil {
        log.Fatal(err)
    }
    if len(features) == 0 {
        break
    }

    for _, f := range features {
        // Process feature
    }
    page++
}

Next Steps