# Centros de costo

> Separe los ingresos y gastos de un emisor por obra, proyecto, sucursal o área: ponga cada factura en un centro de costo y filtre por él.

Un centro de costo es una parte del negocio que el emisor quiere ver por separado: una obra, un proyecto, una sucursal, un área o un vehículo. Cada factura, la que timbra con la API o la que llega del SAT, puede ir en uno, y en la app **Reportes** muestra cuánto entró, cuánto salió y lo que dejó cada uno. Es una etiqueta de Fiscalisto: no cambia el CFDI, sus impuestos ni lo que ve el SAT. Son los mismos de **Ajustes › Centros de costo** en la app, incluidas las reglas por cliente o proveedor que se crean ahí.

## Crear un centro de costo

```bash tab="cURL"
curl https://api.fiscalisto.com/v1/cost_centers \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Obra Norte", "code": "CC-01" }'
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const costCenter = await fiscalisto.costCenters.create({ name: "Obra Norte", code: "CC-01" });
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

cost_center = fiscalisto.cost_centers.create({"name": "Obra Norte", "code": "CC-01"})
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$costCenter = $fiscalisto->costCenters->create(['name' => 'Obra Norte', 'code' => 'CC-01']);
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	costCenter, err := client.CostCenters.Create(ctx, &fiscalisto.CreateCostCenterParams{
		Name: "Obra Norte",
		Code: fiscalisto.String("CC-01"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(costCenter.ID)
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.CreateCostCenterParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var costCenter = fiscalisto.costCenters().create(new CreateCostCenterParams().setName("Obra Norte").setCode("CC-01"));
System.out.println(costCenter.getId());
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var costCenter = await fiscalisto.CostCenters.CreateAsync(new CreateCostCenterParams
{
    Name = "Obra Norte",
    Code = "CC-01",
});
```

Contesta el centro de costo (`ccn_…`) con `invoices`, cuántas facturas tiene. El nombre no se repite en el emisor, sin importar mayúsculas (otro igual contesta `cost_center_exists`); `code` es opcional, para la clave que use su contabilidad. Hasta 500 por emisor.

## Ponerlo al facturar

Mande `cost_center` en la factura:

```bash tab="cURL"
curl https://api.fiscalisto.com/v1/invoices \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -H "Idempotency-Key: avance-obra-norte-3" \
  -H "Content-Type: application/json" \
  -d '{
    "cost_center": "ccn_OufpKqnrvx9p1",
    "customer": { "tax_id": "ICV060329BY0", "legal_name": "INMOBILIARIA CVA", "tax_system": "601", "zip": "33826" },
    "payment_form": "03",
    "items": [{ "description": "Avance de obra 3", "product_key": "72141000", "unit_price": 250000 }]
  }'
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const invoice = await fiscalisto.invoices.create({
  cost_center: "ccn_OufpKqnrvx9p1",
  customer: {
    tax_id: "ICV060329BY0",
    legal_name: "INMOBILIARIA CVA",
    tax_system: "601",
    zip: "33826",
  },
  payment_form: "03",
  items: [
    {
      description: "Avance de obra 3",
      product_key: "72141000",
      unit_price: 250000,
    },
  ],
}, { idempotencyKey: "avance-obra-norte-3" });
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

invoice = fiscalisto.invoices.create({
    "cost_center": "ccn_OufpKqnrvx9p1",
    "customer": {
        "tax_id": "ICV060329BY0",
        "legal_name": "INMOBILIARIA CVA",
        "tax_system": "601",
        "zip": "33826",
    },
    "payment_form": "03",
    "items": [
        {
            "description": "Avance de obra 3",
            "product_key": "72141000",
            "unit_price": 250000,
        },
    ],
}, idempotency_key="avance-obra-norte-3")
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$invoice = $fiscalisto->invoices->create([
    'cost_center' => 'ccn_OufpKqnrvx9p1',
    'customer' => [
        'tax_id' => 'ICV060329BY0',
        'legal_name' => 'INMOBILIARIA CVA',
        'tax_system' => '601',
        'zip' => '33826',
    ],
    'payment_form' => '03',
    'items' => [
        [
            'description' => 'Avance de obra 3',
            'product_key' => '72141000',
            'unit_price' => 250000,
        ],
    ],
], ['idempotency_key' => 'avance-obra-norte-3']);
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	invoice, err := client.Invoices.Create(ctx, &fiscalisto.InvoiceCreate{
		CostCenter: fiscalisto.String("ccn_OufpKqnrvx9p1"),
		Customer: fiscalisto.ObjectOf(fiscalisto.InvoiceCreateCustomer{
			TaxID:     "ICV060329BY0",
			LegalName: "INMOBILIARIA CVA",
			TaxSystem: "601",
			Zip:       "33826",
		}),
		PaymentForm: fiscalisto.String("03"),
		Items: []fiscalisto.InvoiceCreateItem{
			{
				Description: fiscalisto.String("Avance de obra 3"),
				ProductKey:  fiscalisto.String("72141000"),
				UnitPrice:   fiscalisto.Float64(250000),
			},
		},
	}, fiscalisto.WithIdempotencyKey("avance-obra-norte-3"))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(invoice.ID)
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.RequestOptions;
import com.fiscalisto.model.InvoiceCreate;
import com.fiscalisto.model.InvoiceCreateCustomer;
import com.fiscalisto.model.InvoiceCreateItem;
import java.util.List;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var invoice = fiscalisto.invoices().create(new InvoiceCreate()
        .setCostCenter("ccn_OufpKqnrvx9p1")
        .setCustomer(new InvoiceCreateCustomer()
                .setTaxId("ICV060329BY0")
                .setLegalName("INMOBILIARIA CVA")
                .setTaxSystem("601")
                .setZip("33826"))
        .setPaymentForm("03")
        .setItems(List.of(
                new InvoiceCreateItem()
                        .setDescription("Avance de obra 3")
                        .setProductKey("72141000")
                        .setUnitPrice(250000)
        )), RequestOptions.idempotencyKey("avance-obra-norte-3"));
System.out.println(invoice.getId());
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var invoice = await fiscalisto.Invoices.CreateAsync(new InvoiceCreate
{
    CostCenter = "ccn_OufpKqnrvx9p1",
    Customer = new InvoiceCreateCustomer
    {
        TaxId = "ICV060329BY0",
        LegalName = "INMOBILIARIA CVA",
        TaxSystem = "601",
        Zip = "33826",
    },
    PaymentForm = "03",
    Items = new()
    {
        new()
        {
            Description = "Avance de obra 3",
            ProductKey = "72141000",
            UnitPrice = 250000,
        },
    },
}, new RequestOptions { IdempotencyKey = "avance-obra-norte-3" });
```

La factura trae `cost_center` desde que se crea. Sus notas de crédito (`POST /v1/credit_notes`) toman el mismo centro de costo solas, para que resten donde contó la venta. Un centro de costo archivado no se puede usar: restáurelo o use otro.

## Ponerlo, cambiarlo o quitarlo después

Una factura timbrada cambia de centro de costo con `POST /v1/invoices/{id}`; una factura del SAT (por ejemplo, un gasto que recibió el emisor) con `POST /v1/sat_invoices/{id}`. `null` se lo quita:

```bash tab="cURL"
curl https://api.fiscalisto.com/v1/sat_invoices/sat_OufpKqnrvx9p7Bq \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cost_center": "ccn_OufpKqnrvx9p1" }'
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const satInvoice = await fiscalisto.satInvoices.update("sat_OufpKqnrvx9p7Bq", { cost_center: "ccn_OufpKqnrvx9p1" });
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

sat_invoice = fiscalisto.sat_invoices.update("sat_OufpKqnrvx9p7Bq", {"cost_center": "ccn_OufpKqnrvx9p1"})
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$satInvoice = $fiscalisto->satInvoices->update('sat_OufpKqnrvx9p7Bq', ['cost_center' => 'ccn_OufpKqnrvx9p1']);
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	satInvoice, err := client.SatInvoices.Update(ctx, "sat_OufpKqnrvx9p7Bq", &fiscalisto.UpdateSatInvoiceParams{
		CostCenter: fiscalisto.String("ccn_OufpKqnrvx9p1"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(satInvoice.ID)
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.UpdateSatInvoiceParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var satInvoice = fiscalisto.satInvoices().update("sat_OufpKqnrvx9p7Bq", new UpdateSatInvoiceParams().setCostCenter("ccn_OufpKqnrvx9p1"));
System.out.println(satInvoice.getId());
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var satInvoice = await fiscalisto.SatInvoices.UpdateAsync("sat_OufpKqnrvx9p7Bq", new UpdateSatInvoiceParams
{
    CostCenter = "ccn_OufpKqnrvx9p1",
});
```

Los complementos de pago y los traslados no llevan centro de costo (contestan `parameter_invalid`). Solo cambia la etiqueta: el CFDI sigue igual.

## Filtrar por centro de costo

`GET /v1/invoices` y `GET /v1/sat_invoices` aceptan `cost_center`: un `ccn_…`, o `none` para las que todavía no tienen.

```bash tab="cURL"
curl -G https://api.fiscalisto.com/v1/sat_invoices \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -d cost_center=ccn_OufpKqnrvx9p1 \
  -d date_gte=2026-10-01
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

for await (const item of fiscalisto.satInvoices.list({
  cost_center: "ccn_OufpKqnrvx9p1",
  date_gte: "2026-10-01",
})) {
  console.log(item.id);
}
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

for item in fiscalisto.sat_invoices.list({
    "cost_center": "ccn_OufpKqnrvx9p1",
    "date_gte": "2026-10-01",
}):
    print(item["id"])
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

foreach ($fiscalisto->satInvoices->list([
    'cost_center' => 'ccn_OufpKqnrvx9p1',
    'date_gte' => '2026-10-01',
]) as $item) {
    echo $item['id'], "\n";
}
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	for item, err := range client.SatInvoices.ListAutoPaging(ctx, &fiscalisto.ListSatInvoicesParams{
		CostCenter: fiscalisto.String("ccn_OufpKqnrvx9p1"),
		DateGte:    fiscalisto.String("2026-10-01"),
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(item.ID)
	}
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.ListSatInvoicesParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

for (var item : fiscalisto.satInvoices().listAutoPaging(new ListSatInvoicesParams()
        .setCostCenter("ccn_OufpKqnrvx9p1")
        .setDateGte("2026-10-01"))) {
    System.out.println(item.getId());
}
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

await foreach (var item in fiscalisto.SatInvoices.ListAutoPagingAsync(new ListSatInvoicesParams
{
    CostCenter = "ccn_OufpKqnrvx9p1",
    DateGte = "2026-10-01",
}))
    Console.WriteLine(item.Id);
```

## Archivar, juntar o borrar

`POST /v1/cost_centers/{id}` cambia `name` y `code`; `"archived": true` lo archiva (ya no se ponen facturas en él, pero las suyas lo conservan) y `false` lo restaura. `GET /v1/cost_centers` lista los activos; con `include_archived=true`, también los archivados.

`DELETE /v1/cost_centers/{id}` lo borra. Con `move_to` (otro `ccn_…`) sus facturas y reglas pasan a ese, y así junta dos en uno; sin él, sus facturas se quedan sin centro de costo. Borrar no se puede deshacer.

## En la app y con agentes

Lo que haga por la API se ve en la app: **Facturas** filtra por centro de costo y **Reportes** tiene **Resultado por centro de costo** y **Gastos por centro de costo**. Con el [MCP](https://fiscalisto.com/docs/api/agentes), `centros_de_costo` los lista, `poner_centro_costo` pone facturas en uno, `buscar_facturas` filtra con `centro_costo` y `correr_reporte` agrupa con `por: centro`.
