Skip to main content

Quickstart

Quickstart: create an invoice in Go

No official SDK — use net/http (stdlib)

No official Go SDK for Scell.io. The stdlib `net/http` + `encoding/json` covers 100% of needs. For production, use `context.Context` for timeouts and a configured `*http.Client` with `Transport` (retries via `hashicorp/go-retryablehttp`). The REST + snake_case JSON API maps naturally to Go structs (`json:"snake_case"` tags). Compatible with any HTTP framework (Gin, Echo, Fiber, chi).

Key facts

  • Requirements: Go 1.22+
  • No official SDK: stdlib `net/http` is enough
  • Env var: `os.Getenv("SCELL_API_KEY")`
  • HTTP: `net/http` (stdlib) or `hashicorp/go-retryablehttp`
  • Expected output: typed struct with `ID`, `Status`
  • Error codes: check `resp.StatusCode` + decode `errorResponse`

Code example

package main

import (
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

const API = "https://api.scell.io/api/v1"

func idempKey() string { b := make([]byte, 16); rand.Read(b); return hex.EncodeToString(b) }

func call(path string, body any) (map[string]any, error) {
	data, _ := json.Marshal(body)
	req, _ := http.NewRequest("POST", API+path, bytes.NewReader(data))
	req.Header.Set("X-API-Key", os.Getenv("SCELL_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Idempotency-Key", idempKey())
	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Do(req)
	if err != nil { return nil, err }
	defer resp.Body.Close()
	var out map[string]any
	json.NewDecoder(resp.Body).Decode(&out)
	if resp.StatusCode >= 400 { return nil, fmt.Errorf("%d: %v", resp.StatusCode, out) }
	return out, nil
}

func main() {
	seller := map[string]any{
		"siret": "12345678901234", "name": "Ma SAS", "vat_number": "FR12345678901",
		"address": map[string]string{"street": "1 rue Test", "city": "Paris", "postal_code": "75001", "country": "FR"},
	}
	b2b, _ := call("/invoices", map[string]any{
		"format": "factur-x", "profile": "EN16931", "currency": "EUR", "seller": seller,
		"buyer": map[string]any{"siret": "98765432109876", "name": "Client SARL",
			"address": map[string]string{"street": "2 avenue Demo", "city": "Lyon", "postal_code": "69001", "country": "FR"}},
		"lines": []map[string]any{{"description": "Prestation conseil", "quantity": 1, "unit_price": 1000.0, "vat_rate": 20.0}},
	})
	fmt.Printf("B2B: %v (%v)\n", b2b["id"], b2b["status"])

	b2c, _ := call("/invoices", map[string]any{
		"format": "factur-x", "profile": "EN16931", "currency": "EUR", "seller": seller,
		"buyer": map[string]any{"buyer_is_individual": true, "name": "Jean Dupont", "email": "jean@example.com",
			"address": map[string]string{"street": "3 bd Client", "city": "Marseille", "postal_code": "13001", "country": "FR"}},
		"lines": []map[string]any{{"description": "Abonnement", "quantity": 1, "unit_price": 49.90, "vat_rate": 20.0}},
	})
	fmt.Printf("B2C: %v (%v)\n", b2c["id"], b2c["status"])

	sig, _ := call("/signatures", map[string]any{
		"document_url": "https://example.com/contrat.pdf",
		"signers": []map[string]any{{"name": "Jean Dupont", "email": "jean@example.com", "phone": "+33612345678"}},
		"signature_options": map[string]any{"signature_mode": "drawn", "timezone": "Europe/Paris"},
	})
	fmt.Printf("Signature: %v -> %v\n", sig["id"], sig["signing_url"])
}

See also

Your cookie preferences

We use cookies to improve your experience. Essential cookies are always active. Cookie policy.