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

# Create extraction

> Start a new process for extracting tax documents from SAT

## Description

This endpoint starts a process for extracting tax documents from SAT. Extraction is an asynchronous process that can take several minutes depending on the volume of documents.

<Note>
  The extraction process is asynchronous. Use the returned `publicId` to check status or configure webhooks to receive notifications.
</Note>

## Request

<ParamField body="subject" type="object" required>
  Information of the taxpayer from whom to extract documents

  <Expandable title="Propiedades de subject">
    <ParamField body="identifier" type="string" required>
      Taxpayer's RFC (13 characters for legal entities, 10 for individuals)
    </ParamField>

    <ParamField body="name" type="string">
      Company name or taxpayer name (optional)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="credentials" type="object" required>
  Credentials to access SAT

  <Expandable title="Propiedades de credentials">
    <ParamField body="type" type="string" required>
      Credential type. Allowed values: `CIEC`, `FIEL`
    </ParamField>

    <ParamField body="password" type="string" required>
      Password encoded in base64
    </ParamField>

    <ParamField body="privateKey" type="string">
      Private key in base64 (required only for FIEL)
    </ParamField>

    <ParamField body="certificate" type="string">
      Certificate in base64 (required only for FIEL)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="options" type="object" required>
  Extraction options

  <Expandable title="Propiedades de options">
    <ParamField body="informationType" type="string" required>
      Type of information to extract: `INVOICE`, `TAX_STATUS`, `TAX_RETENTION`
    </ParamField>

    <ParamField body="period" type="object" required>
      Time period for extraction

      <Expandable title="period properties">
        <ParamField body="from" type="string" required>
          Start date in YYYY-MM-DD format
        </ParamField>

        <ParamField body="to" type="string" required>
          End date in YYYY-MM-DD format
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="direction" type="string">
      For invoices: `RECEIVED` or `ISSUED`. Default is `RECEIVED`
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="filters" type="object">
  Optional filters for extraction

  <Expandable title="Propiedades de filters">
    <ParamField body="emitters" type="array">
      List of issuer RFCs to filter documents
    </ParamField>

    <ParamField body="receivers" type="array">
      List of receiver RFCs to filter documents
    </ParamField>

    <ParamField body="minAmount" type="number">
      Minimum amount of documents
    </ParamField>

    <ParamField body="maxAmount" type="number">
      Maximum amount of documents
    </ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="publicId" type="string">
  Unique extraction ID for subsequent queries
</ResponseField>

<ResponseField name="status" type="string">
  Current status: `PENDING`, `PROCESSING`, `COMPLETED`, `FAILED`
</ResponseField>

<ResponseField name="createdAt" type="string">
  Creation timestamp in ISO 8601 format
</ResponseField>

<ResponseField name="options" type="object">
  Copy of the options sent in the request
</ResponseField>

<ResponseField name="subject" type="object">
  Processed taxpayer information

  <Expandable title="Propiedades de subject">
    <ResponseField name="identification" type="string">
      Taxpayer's RFC
    </ResponseField>

    <ResponseField name="fullName" type="string">
      Full name obtained from SAT
    </ResponseField>

    <ResponseField name="personType" type="string">
      Person type: `MORAL` or `FISICA`
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="discoveryCount" type="number">
  Number of documents found (0 initially)
</ResponseField>

<ResponseField name="completedCount" type="number">
  Number of documents processed successfully
</ResponseField>

<ResponseField name="failedCount" type="number">
  Number of documents that failed to process
</ResponseField>

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.taxo.co/v1/extractions" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "subject": {
        "identifier": "ABC010101ABC",
        "name": "Empresa ABC S.A. de C.V."
      },
      "credentials": {
        "type": "CIEC",
        "password": "bXlQYXNzd29yZDEyM0A="
      },
      "options": {
        "informationType": "INVOICE",
        "period": {
          "from": "2024-01-01",
          "to": "2024-12-31"
        },
        "direction": "RECEIVED"
      },
      "filters": {
        "emitters": ["XYZ020202XYZ"],
        "minAmount": 1000
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.taxo.co/v1/extractions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.TAXO_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subject: {
        identifier: 'ABC010101ABC',
        name: 'Empresa ABC S.A. de C.V.'
      },
      credentials: {
        type: 'CIEC',
        password: Buffer.from('myPassword123@').toString('base64')
      },
      options: {
        informationType: 'INVOICE',
        period: {
          from: '2024-01-01',
          to: '2024-12-31'
        },
        direction: 'RECEIVED'
      },
      filters: {
        emitters: ['XYZ020202XYZ'],
        minAmount: 1000
      }
    })
  });

  const extraction = await response.json();
  console.log('Extracción creada:', extraction.publicId);
  ```

  ```python Python theme={null}
  import requests
  import base64

  # Encode password
  password_b64 = base64.b64encode('myPassword123@'.encode()).decode()

  payload = {
      'subject': {
          'identifier': 'ABC010101ABC',
          'name': 'Empresa ABC S.A. de C.V.'
      },
      'credentials': {
          'type': 'CIEC',
          'password': password_b64
      },
      'options': {
          'informationType': 'INVOICE',
          'period': {
              'from': '2024-01-01',
              'to': '2024-12-31'
          },
          'direction': 'RECEIVED'
      },
      'filters': {
          'emitters': ['XYZ020202XYZ'],
          'minAmount': 1000
      }
  }

  response = requests.post(
      'https://api.taxo.co/v1/extractions',
      json=payload,
      headers={
          'Authorization': f'Bearer {os.environ["TAXO_API_KEY"]}',
          'Content-Type': 'application/json'
      }
  )

  extraction = response.json()
  print(f'Extraction created: {extraction["publicId"]}')
  ```

  ```java Java theme={null}
  // Usando Spring RestTemplate
  RestTemplate restTemplate = new RestTemplate();

  Map<String, Object> payload = new HashMap<>();
  payload.put("subject", Map.of(
      "identifier", "ABC010101ABC",
      "name", "Empresa ABC S.A. de C.V."
  ));

  payload.put("credentials", Map.of(
      "type", "CIEC",
      "password", Base64.getEncoder().encodeToString("myPassword123@".getBytes())
  ));

  payload.put("options", Map.of(
      "informationType", "INVOICE",
      "period", Map.of(
          "from", "2024-01-01",
          "to", "2024-12-31"
      ),
      "direction", "RECEIVED"
  ));

  HttpHeaders headers = new HttpHeaders();
  headers.set("Authorization", "Bearer " + System.getenv("TAXO_API_KEY"));
  headers.setContentType(MediaType.APPLICATION_JSON);

  HttpEntity<Map<String, Object>> request = new HttpEntity<>(payload, headers);

  ResponseEntity<Map> response = restTemplate.postForEntity(
      "https://api.taxo.co/v1/extractions",
      request,
      Map.class
  );

  System.out.println("Extraction created: " + response.getBody().get("publicId"));
  ```
</CodeGroup>

## Successful response

```json theme={null}
{
  "publicId": "JOB20250104123456789A",
  "status": "PENDING",
  "createdAt": "2025-01-04T12:34:56.789Z",
  "options": {
    "informationType": "INVOICE",
    "period": {
      "from": "2024-01-01",
      "to": "2024-12-31"
    },
    "direction": "RECEIVED"
  },
  "subject": {
    "identification": "ABC010101ABC",
    "fullName": "Empresa ABC S.A. de C.V.",
    "personType": "MORAL"
  },
  "discoveryCount": 0,
  "completedCount": 0,
  "failedCount": 0
}
```

## Common errors

<ResponseExample>
  ```json Error 400 - Invalid RFC theme={null}
  {
    "error": {
      "code": "INVALID_RFC",
      "message": "The provided RFC does not have a valid format",
      "details": {
        "field": "subject.identifier",
        "provided": "ABC01010",
        "expected": "RFC of 10 or 13 characters"
      }
    }
  }
  ```

  ```json Error 401 - Incorrect SAT credentials theme={null}
  {
    "error": {
      "code": "INVALID_CREDENTIALS",
      "message": "The CIEC credentials are incorrect",
      "details": {
        "field": "credentials.password",
        "hint": "Verify that the password is encoded in base64"
      }
    }
  }
  ```

  ```json Error 429 - Rate limit exceeded theme={null}
  {
    "error": {
      "code": "RATE_LIMIT_EXCEEDED",
      "message": "You have exceeded the limit of 10 extractions per hour",
      "details": {
        "limit": 10,
        "window": "1 hour",
        "resetAt": "2025-01-04T14:00:00Z"
      }
    }
  }
  ```
</ResponseExample>

## Important notes

<Warning>
  **Passwords:** Always encode passwords in base64 before sending them. Plain text passwords will be rejected.
</Warning>

<Tip>
  **Large periods:** For date ranges greater than 3 months, consider splitting the extraction into multiple requests for better performance.
</Tip>

<Info>
  **Asynchronous status:** Once the extraction is created, use the [Check status](/api-reference/taxo-b2b/endpoints/get-extraction) endpoint to monitor progress.
</Info>
