> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stockshift.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> Un cliente de Go para la API de StockShift. Tiene un método por cada operación de la referencia de la API y un tipo de Go para cada solicitud y respuesta, todo generado a partir del documento OpenAPI de la API.

Requiere Go 1.26 o posterior. No tiene dependencias fuera de la biblioteca estándar.

## Instalación

```bash theme={null}
go get github.com/StockShift/go-sdk
```

```go theme={null}
import stockshift "github.com/StockShift/go-sdk"
```

## Inicio rápido

Crea un artículo y luego lista las existencias disponibles:

```go theme={null}
client := stockshift.NewClient(stockshift.WithToken(os.Getenv("STOCKSHIFT_TOKEN")))

item, err := client.Catalog.CreateItem(ctx, &stockshift.CreateItemRequest{
	SKU:       "BOLT-M4",
	Name:      "M4 hex bolt",
	Type:      stockshift.ItemTypeStocked,
	MakeOrBuy: stockshift.MakeOrBuyBuy,
})
if err != nil {
	return err
}

for row, err := range client.Inventory.ListStockOnHandAll(ctx, nil) {
	if err != nil {
		return err
	}
	fmt.Println(row.SKU, row.LocationCode, row.AvailableToPromise)
}
```

## Autenticación

Pasa una clave de API o un token de acceso OAuth con `WithToken`. Crea una clave de API en la app, en Configuración > Acceso > Claves de API. La clave actúa como el miembro que la creó, y cada llamada necesita tanto el permiso del miembro como uno de los alcances de la clave.

Para un token OAuth que vence, pasa una función con `WithTokenFunc`. El cliente la llama antes de cada solicitud, y el error que devuelva es el error de la llamada:

```go theme={null}
client := stockshift.NewClient(stockshift.WithTokenFunc(func(ctx context.Context) (string, error) {
	return tokens.Current(ctx)
}))
```

Otras opciones:

| Opción | Valor predeterminado | Significado |
| - | - | - |
| `WithBaseURL` | `https://app.stockshift.io/api/v1` | Dónde está la API. |
| `WithHTTPClient` | un `http.Client` con un tiempo de espera de 60 segundos | El cliente que envía las solicitudes. Su `Timeout` limita cada intento. |
| `WithMaxRetries` | `2` | Reintentos para una llamada que se puede reintentar. |
| `WithMaxRetryAfter` | un minuto | El `Retry-After` más largo que vale la pena esperar. |
| `WithHeader` | ninguno | Un encabezado que se envía en cada llamada. |

Un `Client` se puede usar con seguridad desde muchas goroutines. Crea uno y compártelo.

## Hacer llamadas

Cada área de la API es un campo del cliente, como `Catalog` o `Inventory`, con un método por cada operación. Todos los métodos reciben primero un `context.Context`, luego los parámetros de ruta, luego el cuerpo y luego los parámetros de consulta:

```go theme={null}
item, err := client.Catalog.GetItem(ctx, "01J8QZ4M...")

page, err := client.Catalog.ListItems(ctx, &stockshift.CatalogListItemsParams{
	Search: stockshift.Ptr("bolt"),
	Status: stockshift.Ptr(stockshift.ItemStatusActive),
})
```

El comentario de documentación de cada método indica su ruta, como `GET /catalog/items/{item}`. Un método devuelve el `data` de la respuesta como un tipo generado. Una respuesta vacía devuelve solo un error, una exportación CSV sus bytes y un archivo el `*http.Response`, cuyo cuerpo debes cerrar.

Cancela el contexto para detener una llamada, incluidos los reintentos y las esperas.

### Campos opcionales

Un parámetro de consulta que puedes omitir es un puntero. `stockshift.Ptr` crea uno a partir de un valor.

Un campo del cuerpo de la solicitud que puedes omitir es un `Opt`. Su valor cero omite el campo, `stockshift.Value(v)` envía `v` y `stockshift.Null[T]()` envía `null`, que vacía el campo donde la API lo permite:

```go theme={null}
_, err := client.Catalog.UpdateItem(ctx, id, &stockshift.ItemFieldsRequest{
	SKU:       "BOLT-M4",
	Name:      "M4 hex bolt",
	Type:      stockshift.ItemTypeStocked,
	MakeOrBuy: stockshift.MakeOrBuyBuy,
	Brand:     stockshift.Null[string](),
})
```

### Otros endpoints

`client.Do` llama a cualquier ruta y decodifica la respuesta JSON en un valor que le pasas. Úsalo para un endpoint que se agregó a la API después de esta versión del paquete:

```go theme={null}
var out struct {
	Data stockshift.ItemResource `json:"data"`
}
err := client.Do(ctx, http.MethodGet, "/catalog/items/"+id, nil, nil, &out)
```

## Paginación

Una lista que puede crecer devuelve una página a la vez. Cada lista paginada tiene un segundo método que termina en `All` y devuelve un `iter.Seq2`. Sigue los cursores y entrega cada registro:

```go theme={null}
for item, err := range client.Catalog.ListItemsAll(ctx, &stockshift.CatalogListItemsParams{Search: stockshift.Ptr("bolt")}) {
	if err != nil {
		return err
	}
	fmt.Println(item.SKU)
}
```

Obtiene la página siguiente solo cuando el ciclo la necesita, así que un `break` lo detiene. Un error termina el ciclo. Para paginar a mano, asigna a `After` el `NextCursor` de cada página hasta que sea `nil`.

## Errores

Una llamada que la API rechaza devuelve un `*APIError` que contiene el cuerpo de detalles del problema de RFC 9457. Decide según `Code`, que es estable. `Problem.Detail` está escrito para personas y puede cambiar.

```go theme={null}
_, err := client.Catalog.CreateItem(ctx, body)

var apiErr *stockshift.APIError
if errors.As(err, &apiErr) && apiErr.Code == "validation_failed" {
	fmt.Println(apiErr.Problem.Errors) // map[sku:[Another item already has the SKU BOLT-M4.]]
}
```

`APIError` también tiene `StatusCode` y `Header`. Una llamada que no recibe respuesta, porque falló la red o el intento agotó el tiempo de espera, devuelve un `*ConnectionError` que envuelve la causa. Cuando el contexto termina, la llamada devuelve el error del contexto.

## Reintentos y claves de idempotencia

El cliente reintenta un `429` después del tiempo que indica `Retry-After`. Lo hace con todos los métodos, porque la API no ejecutó la llamada. Si `Retry-After` es mayor que `WithMaxRetryAfter`, devuelve el error en lugar de esperar.

Un `5xx` o una falla de red se reintenta para `GET`, `PUT` y `DELETE`, con una breve espera entre intentos. Un `POST` o `PATCH` solo se reintenta cuando le das una clave de idempotencia, para que un reintento no pueda hacer el cambio dos veces:

```go theme={null}
run, err := client.Integrations.PushStockNow(ctx, connectionID, stockshift.IdempotencyKey(rand.Text()))
```

Usa una clave nueva para cada cambio que quieras hacer. Los endpoints que respetan la clave lo indican en la referencia de la API. `CallMaxRetries` y `CallHeader` cambian una sola llamada de la misma manera.

## Webhooks

Revisa el encabezado `StockShift-Signature` antes de confiar en una entrega. `WebhookVerifier.Verify` necesita el cuerpo sin procesar, exactamente como llegó:

```go theme={null}
verifier := stockshift.WebhookVerifier{Secret: os.Getenv("STOCKSHIFT_WEBHOOK_SECRET")}

http.HandleFunc("POST /webhooks/stockshift", func(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	event, err := verifier.Verify(body, r.Header.Get(stockshift.SignatureHeader))
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	if event.Type == stockshift.EventInventoryStockAdjusted {
		var data stockshift.InventoryStockAdjustedData
		if err := json.Unmarshal(event.Data, &data); err != nil {
			http.Error(w, "", http.StatusBadRequest)
			return
		}
		fmt.Println(data.ItemID, data.Quantity)
	}
	w.WriteHeader(http.StatusNoContent)
})
```

Rechaza una entrega de más de cinco minutos de antigüedad. Asigna `Tolerance` para cambiarlo. Los reintentos de un evento conservan su `ID`, así que guárdalo y omite los eventos que ya procesaste.

Cada tipo de evento tiene una constante, como `EventInventoryStockAdjusted`, cuyo comentario de documentación indica el tipo en el que se decodifica su `Data`. Para probar tu propio receptor, `SignWebhook` firma un payload igual que StockShift.

## Versiones

El módulo sigue el versionado semántico. La versión mayor cambia cuando la API cambia de una forma que puede romper tu código, como un campo eliminado o un parámetro obligatorio nuevo. En Go una versión mayor nueva también cambia la ruta de importación, como `github.com/StockShift/go-sdk/v2`. Los endpoints y campos nuevos llegan en versiones menores. `APIVersion` contiene la versión de la referencia de la API con la que se compiló el módulo.

Se admiten las dos versiones más recientes de Go, igual que hace el equipo de Go.


## Related topics

- [SDK](https://docs.stockshift.io/es/sdks/index.md)
- [StockShift para desarrolladores](https://docs.stockshift.io/es/index.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.