Skip to content

cycletask/go-sdk

Repository files navigation

CycleTask Go SDK

Official Go client for the CycleTask Mail Forwarding API.

  • Zero external dependencies (stdlib only)
  • Context-aware with cancellation support
  • Automatic retry with exponential backoff on 429/5xx
  • Idiomatic Go: functional options, pointer helpers, exported types

Install

go get github.com/cycletask/go-sdk

Requires Go 1.21+.

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    cycletask "github.com/cycletask/go-sdk"
)

func main() {
    client := cycletask.New("ct_live_your_api_key")
    ctx := context.Background()

    domains, err := client.Domains.List(ctx)
    if err != nil {
        log.Fatal(err)
    }
    for _, d := range domains {
        fmt.Printf("%s verified=%t\n", d.Domain, d.IsVerified)
    }
}

Client Options

client := cycletask.New("ct_live_key",
    cycletask.WithBaseURL("https://custom.api.com/api"),
    cycletask.WithTimeout(15 * time.Second),
    cycletask.WithMaxRetries(5),
    cycletask.WithHTTPClient(myHTTPClient),
)
Option Default Description
WithBaseURL https://api.task-cycle.com/api Override the API base URL
WithTimeout 30s HTTP client timeout (ignored if WithHTTPClient is set)
WithMaxRetries 3 Max retry attempts for 429/5xx errors
WithHTTPClient nil Use a custom *http.Client

API Reference

Domains

// List all domains
domains, err := client.Domains.List(ctx)

// Get a single domain
domain, err := client.Domains.Get(ctx, "domain_id")

// Create a domain
domain, err := client.Domains.Create(ctx, &cycletask.CreateDomainParams{
    Domain: "example.com",
})

// Verify a domain
domain, err := client.Domains.Verify(ctx, "domain_id")

// Get required DNS records
records, err := client.Domains.GetDNSRecords(ctx, "domain_id")

// Delete a domain
err := client.Domains.Delete(ctx, "domain_id")

Aliases

// List aliases with pagination and filters
resp, err := client.Aliases.List(ctx, &cycletask.ListAliasesParams{
    Page:   1,
    Limit:  25,
    Search: "hello",
    Domain: "domain_id",
    Status: "active",
    Sort:   "-createdAt",
})
// resp.Data contains []Alias
// resp.Pagination contains page info

// Create an alias
alias, err := client.Aliases.Create(ctx, &cycletask.CreateAliasParams{
    Alias:        "hello",
    DomainID:     "domain_id",
    Destinations: []string{"me@gmail.com", "backup@gmail.com"},
    Description:  "My alias",
})

// Update an alias (pointer fields for partial updates)
alias, err := client.Aliases.Update(ctx, "alias_id", &cycletask.UpdateAliasParams{
    IsActive:     cycletask.Bool(false),
    Description:  cycletask.String("Disabled"),
    Destinations: cycletask.Strings([]string{"new@gmail.com"}),
})

// Get forwarding logs for an alias
logs, err := client.Aliases.GetLogs(ctx, "alias_id", &cycletask.ListLogsParams{
    Page:  1,
    Limit: 50,
})

// Delete an alias
err := client.Aliases.Delete(ctx, "alias_id")

Stats

// Get overview statistics
overview, err := client.Stats.Overview(ctx)
// overview.TotalForwarded, overview.TotalFailed, etc.

// Get chart data
chart, err := client.Stats.Chart(ctx, &cycletask.ChartParams{Days: 30})
// chart is []ChartDataPoint with Date, Forwarded, Failed

// Get forwarding logs (global)
logs, err := client.Stats.Logs(ctx, &cycletask.ListLogsParams{
    Page:   1,
    Limit:  100,
    Status: "delivered",
})

Status (Public, No Auth Required)

// Get service status
status, err := client.Status.Get(ctx)

// Get uptime information
uptime, err := client.Status.Uptime(ctx)

// Get incidents
incidents, err := client.Status.Incidents(ctx)

Error Handling

All API errors are returned as *cycletask.Error:

domain, err := client.Domains.Get(ctx, "bad_id")
if err != nil {
    var apiErr *cycletask.Error
    if errors.As(err, &apiErr) {
        fmt.Printf("Status: %d\n", apiErr.StatusCode)
        fmt.Printf("Code: %s\n", apiErr.Code)
        fmt.Printf("Message: %s\n", apiErr.Message)
    }
}

Convenience helpers:

if cycletask.IsNotFound(err) { ... }
if cycletask.IsRateLimited(err) { ... }
if cycletask.IsUnauthorized(err) { ... }

Retry Behavior

The client automatically retries on:

  • 429 Too Many Requests — respects Retry-After header
  • 5xx Server Errors — exponential backoff (500ms, 1s, 2s, ...)
  • Network errors — connection failures, timeouts

Retries respect context cancellation. Configure with WithMaxRetries(n).

Pointer Helpers

Use these to set optional fields in update params:

cycletask.Bool(true)                      // *bool
cycletask.String("value")                 // *string
cycletask.Int(42)                         // *int
cycletask.Strings([]string{"a", "b"})     // *[]string

License

MIT

About

Official Go SDK for CycleTask Mail Forwarding API

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages