Skip to content

FAQ and Troubleshooting

Igor Sazonov edited this page Sep 6, 2026 · 1 revision

This page addresses frequent integration questions. Begin with Getting Started if you have not yet run a successful request, and use Service Reference to verify the SDK method and request type for your use case.

Why do I receive 401 or 403?

A protected SocialKit operation requires an access key. SocialKit documents 401 when a key is missing and 403 when a supplied key is invalid; a 403 with code insufficient_credits indicates a valid key with an insufficient balance. The Go SDK maps these outcomes to ErrUnauthorized, ErrForbidden, and ErrInsufficientCredits respectively. 1 2

Symptom Likely cause What to do
ErrUnauthorized / HTTP 401 The key is absent from NewClient or empty. Confirm that SOCIALKIT_ACCESS_KEY is set in the running process.
ErrForbidden / HTTP 403 The key is invalid or not accepted for the request. Verify the key in the SocialKit dashboard and avoid surrounding whitespace.
ErrInsufficientCredits / HTTP 403 The project balance cannot cover the request. Use errors.As to inspect InsufficientCreditsError and let an authorised account owner decide how to proceed.

By default the client sends x-access-key. You normally do not need WithKeyInQuery(true); it exists only for compatibility with integrations that require access_key in query/body form. 1 3

Why is Status.Get working without a key but Credits.Get is not?

SocialKit documents GET /status as its public endpoint. Credits and scraping operations require authentication, so a health check should not be considered proof that your access key or account configuration is correct. 1 4

// Public health check.
status, _, err := client.Status.Get(ctx)

// Authenticated balance check.
credits, _, err := client.Credits.Get(ctx)

Why is a response field nil?

Many numeric, boolean, cursor, and header-derived fields are pointers because an upstream response may omit them. A nil pointer is not automatically an error; it means the value was not provided in the decoded payload or header. Nil-check before dereferencing. 5

if stats.Views != nil {
    fmt.Printf("views: %d\n", *stats.Views)
}

if meta.RateLimitRemaining != nil {
    fmt.Printf("requests remaining: %d\n", *meta.RateLimitRemaining)
}

Do not use a zero value to infer that the upstream data was present. For example, 0 views and an absent view count have different meanings.

Why is there no pagination cursor for YouTube comments?

The SDK’s YouTubeComments model is a flat list without cursor fields. This mirrors the compatibility assessment of the current upstream contract. TikTok, Instagram, and Facebook comment result models include optional HasMore and Cursor fields; X/Twitter tweet listings use NextCursor. 5 6

Use only the continuation field supplied by the result type. See Pagination and Listings for a safe loop pattern.

Why does a list request reject my limit before calling the API?

The SDK performs selected local validations to prevent request values outside known endpoint limits. For example, it rejects a YouTube comment limit above 100, a YouTube videos limit above 30, a TikTok channel-videos/search/hashtag limit above 100, and a LinkedIn company-posts limit above 50. The Instagram reels search wrapper also rejects a page other than 1 when Page is set. 6

These guards are SDK behavior. Endpoint capabilities can evolve, so compare a validation failure with the installed SDK version and the upstream API reference before assuming a service issue.

Why did the SDK not retry my request?

Retries are off by default. Configure them through WithRetry(maxAttempts, baseDelay) if your application has made an explicit idempotency and cost decision. With retries enabled, the SDK retries transport errors and 429/selected 5xx responses, but not 400, 401, 403, or 404. 7 8

client := socialkit.NewClient(key, socialkit.WithRetry(3, time.Second))

A POST operation may be billable; enabling retries makes repeated POST attempts possible. Use a bounded retry policy and design your application to avoid duplicate downstream processing.

How do I handle a long download?

Use client.Downloads.Start followed by client.Downloads.Wait, or poll with client.Downloads.Get. The upstream v2 download flow uses queued, processing, ready, and failed states. A ready job carries a temporary URL; a job observed as failed by Wait produces ErrAsyncJobFailed. 9 10

job, _, err := client.Downloads.Start(ctx, "facebook", &socialkit.V2DownloadRequest{URL: videoURL})
if err != nil {
    return err
}

ready, _, err := client.Downloads.Wait(ctx, job.JobID, &socialkit.WaitOptions{
    Interval:    3 * time.Second,
    MaxAttempts: 20,
})
if err != nil {
    return err
}
fmt.Println(ready.DownloadURL)

Why does Summary.Extra contain raw JSON?

The SDK stores unknown summary fields in map[string]json.RawMessage to support custom or future upstream response fields without pretending they are a fixed schema. Unmarshal an Extra entry into a local Go type that your application validates. 5

var labels []string
if raw, ok := summary.Extra["labels"]; ok {
    if err := json.Unmarshal(raw, &labels); err != nil {
        return err
    }
}

Why are some fields json.RawMessage or map[string]interface{}?

Certain upstream objects do not have a reliable fixed property set. The SDK preserves those values as raw or generic JSON rather than manufacturing a narrow type. Examples include the LinkedIn post payload and parts of X/Twitter thread and tweet data. This helps prevent the SDK from discarding fields when the upstream API evolves. 5 6

How do I report a problem?

For a suspected SDK bug or documentation defect, open a GitHub issue in the source repository with your SDK version, a minimal redacted code sample, the method called, HTTP status/SDK error, and safe ResponseMeta details. Do not include access keys, full confidential URLs, or unreviewed raw third-party payloads. For endpoint-specific behavior, compare with SocialKit’s live API documentation first. 11

References

Clone this wiki locally