Getting Started

This guide walks you through installing the Kard Go SDK, authenticating with the Kard API, and making your first request.

Prerequisites

  • Go 1.18+
  • KARD_CLIENT_ID and KARD_CLIENT_SECRET

Create a Client

Import and instantiate the client using your credentials.

This SDK supports two authentication methods:

OAuauth Client Credentials

1client := client.NewClient(
2 option.WithToken("<YOUR_ACCESS_TOKEN>"),
3)

Bearer Token Authentication

1client := client.NewClient(
2 option.WithClientCredentials(
3 "<YOUR_CLIENT_ID>",
4 "<YOUR_CLIENT_SECRET>",
5 ),
6)

The client automatically handles authentication, retries, and timeouts.

Environments

This SDK allows you to configure different environments for API requests with the option.WithBaseURL option.

1client := client.NewClient(
2 option.WithBaseURL(kard.Environments.Production),
3)

Make Your First API Calls

1. Creating a User:

1package example
2
3import (
4 context "context"
5
6 kard "github.com/KardFinancial/kard-go-sdk"
7 client "github.com/KardFinancial/kard-go-sdk/client"
8 option "github.com/KardFinancial/kard-go-sdk/option"
9)
10
11func do() {
12 client := client.NewClient(
13 option.WithClientCredentials(
14 "<clientId>",
15 "<clientSecret>",
16 ),
17 )
18 request := &kard.CreateUsersObject{
19 Data: []*kard.UserRequestDataUnion{
20 &kard.UserRequestDataUnion{
21 User: &kard.UserRequestData{
22 Id: "1234567890",
23 Attributes: &kard.UserRequestAttributes{
24 ZipCode: kard.String(
25 "11238",
26 ),
27 EnrolledRewards: []kard.EnrolledRewardsType{
28 kard.EnrolledRewardsTypeCardlinked,
29 },
30 Email: kard.String(
31 "user@example.com",
32 ),
33 HashedEmail: kard.String(
34 "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3e2d8a5b76e45a1d4c4e2e3a1",
35 ),
36 PhoneNumber: kard.String(
37 "+14155552671",
38 ),
39 BirthYear: kard.String(
40 "1990",
41 ),
42 HistoricalTransactionsSent: kard.Bool(
43 true,
44 ),
45 },
46 },
47 },
48 },
49 }
50 client.Users.Create(
51 context.TODO(),
52 "organization-123",
53 request,
54 )
55}

To enhance offer targeting and attribution, you can include a hashed email (HEM) when creating users. The SDK includes a built-in hem.GenerateHEM utility that normalizes and hashes email addresses:

1package example
2
3import (
4 context "context"
5
6 kard "github.com/KardFinancial/kard-go-sdk"
7 client "github.com/KardFinancial/kard-go-sdk/client"
8 hem "github.com/KardFinancial/kard-go-sdk/hem"
9 option "github.com/KardFinancial/kard-go-sdk/option"
10)
11
12func do() {
13 client := client.NewClient(
14 option.WithClientCredentials(
15 "<clientId>",
16 "<clientSecret>",
17 ),
18 )
19
20 hashedEmail, err := hem.GenerateHEM("Jane.Doe+work@gmail.com")
21 if err != nil {
22 return
23 }
24
25 request := &kard.CreateUsersObject{
26 Data: []*kard.UserRequestDataUnion{
27 &kard.UserRequestDataUnion{
28 User: &kard.UserRequestData{
29 Id: "1234567890",
30 Attributes: &kard.UserRequestAttributes{
31 EnrolledRewards: []kard.EnrolledRewardsType{
32 kard.EnrolledRewardsTypeCardlinked,
33 },
34 HashedEmail: kard.String(
35 hashedEmail,
36 ),
37 },
38 },
39 },
40 },
41 }
42 client.Users.Create(
43 context.TODO(),
44 "organization-123",
45 request,
46 )
47}

The function normalizes the email before hashing (removes whitespace, lowercases, and handles Gmail-specific rules like dot and + suffix removal). It returns an error for invalid inputs.

2. Fetching Offers for User with Extended API:

1package example
2
3import (
4 context "context"
5
6 kard "github.com/KardFinancial/kard-go-sdk"
7 client "github.com/KardFinancial/kard-go-sdk/client"
8 option "github.com/KardFinancial/kard-go-sdk/option"
9)
10
11func do() {
12 client := client.NewClient(
13 option.WithClientCredentials(
14 "<clientId>",
15 "<clientSecret>",
16 ),
17 )
18 request := &kard.GetOffersByUserRequest{
19 PageSize: kard.Int(
20 1,
21 ),
22 FilterIsTargeted: kard.Bool(
23 true,
24 ),
25 Sort: kard.String(
26 "-startDate",
27 ),
28 SupportedComponents: []*kard.ComponentType{
29 kard.ComponentTypeShortDescription.Ptr(),
30 kard.ComponentTypeLongDescription.Ptr(),
31 kard.ComponentTypeCta.Ptr(),
32 kard.ComponentTypeTags.Ptr(),
33 kard.ComponentTypeDetailTags.Ptr(),
34 kard.ComponentTypeBaseReward.Ptr(),
35 },
36 }
37 client.Users.Rewards.Offers(
38 context.TODO(),
39 "organization-123",
40 "1234567890",
41 request,
42 )
43}

3. Submitting Transaction for User:

1package example
2
3import (
4 context "context"
5
6 kard "github.com/KardFinancial/kard-go-sdk"
7 client "github.com/KardFinancial/kard-go-sdk/client"
8 option "github.com/KardFinancial/kard-go-sdk/option"
9)
10
11func do() {
12 client := client.NewClient(
13 option.WithClientCredentials(
14 "<clientId>",
15 "<clientSecret>",
16 ),
17 )
18 request := &kard.CreateTransactionsObject{
19 Data: []*kard.TransactionsDataUnion{
20 &kard.TransactionsDataUnion{
21 Transaction: &kard.TransactionsData{
22 Id: "12345610",
23 Attributes: &kard.TransactionsAttributes{
24 UserId: "1234567890",
25 Amount: 1000,
26 Subtotal: kard.Int(
27 800,
28 ),
29 Status: "APPROVED",
30 Currency: "USD",
31 Description: "ADVANCEAUTO",
32 AuthorizationDate: "2021-07-02T17:47:06Z",
33 PaymentType: kard.String(
34 "CARD",
35 ),
36 Direction: "DEBIT",
37 Merchant: &kard.Merchant{
38 Id: "12345678901234567",
39 Name: "ADVANCEAUTO",
40 AddrStreet: kard.String(
41 "125 Main St",
42 ),
43 AddrCity: kard.String(
44 "Philadelphia",
45 ),
46 AddrState: kard.String(
47 "PA",
48 ),
49 AddrZipcode: kard.String(
50 "19147",
51 ),
52 AddrCountry: kard.String(
53 "United States",
54 ),
55 Latitude: kard.String(
56 "37.9419429",
57 ),
58 Longitude: kard.String(
59 "-73.1446869",
60 ),
61 StoreId: kard.String(
62 "12345",
63 ),
64 },
65 CardBin: "123456",
66 CardLastFour: "4321",
67 AuthorizationCode: kard.String(
68 "123456",
69 ),
70 RetrievalReferenceNumber: kard.String(
71 "100804333919",
72 ),
73 SystemTraceAuditNumber: kard.String(
74 "333828",
75 ),
76 AcquirerReferenceNumber: kard.String(
77 "1234567890123456789012345678",
78 ),
79 TransactionId: "12345611",
80 },
81 },
82 },
83 },
84 }
85 client.Transactions.Create(
86 context.TODO(),
87 "organization-123",
88 request,
89 )
90}

All SDK methods return typed responses and typed errors.

Handling Errors

If an API request fails (4xx or 5xx), the SDK returns a structured error compatible with errors.Is and errors.As.

1response, err := client.Users.Create(...)
2if err != nil {
3 var apiError *core.APIError
4 if errors.As(err, apiError) {
5 // Do something with the API error ...
6 }
7 return err
8}

Common Configuration Options

Configure Retries

Retries are enabled by default (max 2 attempts) with exponential backoff. The SDK retries on status codes 408, 429, and 5xx. Configure with option.WithMaxAttempts:

1client := client.NewClient(
2 option.WithMaxAttempts(1),
3)
4
5response, err := client.Users.Create(
6 ...,
7 option.WithMaxAttempts(1),
8)

Set a Timeout

Use the standard context library to set a per-request timeout.

1ctx, cancel := context.WithTimeout(ctx, time.Second)
2defer cancel()
3
4response, err := client.Users.Create(ctx, ...)

Access Raw HTTP Responses

To inspect headers or status codes, use WithRawResponse.

1response, err := client.Users.WithRawResponse.Create(...)
2if err != nil {
3 return err
4}
5fmt.Printf("Got response headers: %v", response.Header)
6fmt.Printf("Got status code: %d", response.StatusCode)

Explicit Null

To send an explicit null through an optional parameter, use the setter methods on the request object; they flip a bit in explicitFields so the property is serialized rather than omitted.

1type ExampleRequest struct {
2 // An optional string parameter.
3 Name *string `json:"name,omitempty" url:"-"`
4
5 // Private bitmask of fields set to an explicit value and therefore not to be omitted
6 explicitFields *big.Int `json:"-" url:"-"`
7}
8
9request := &ExampleRequest{}
10request.SetName(nil)
11
12response, err := client.Users.Create(ctx, request, ...)

Custom HTTP Client

A variety of request options are included to adapt the behavior of the library, which includes configuring authorization tokens, or providing your own instrumented *http.Client.

Providing your own *http.Client is recommended. Otherwise, the http.DefaultClient will be used, and your client will wait indefinitely for a response (unless the per-request, context-based timeout is used).

1// Specify default options applied on every request.
2client := client.NewClient(
3 option.WithToken("<YOUR_API_KEY>"),
4 option.WithHTTPClient(
5 &http.Client{
6 Timeout: 5 * time.Second,
7 },
8 ),
9)
10
11// Specify options for an individual request.
12response, err := client.Users.Create(
13 ...,
14 option.WithToken("<YOUR_API_KEY>"),
15)