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

# Tax credits

> Discover R&D credits, understand their amounts, and distinguish income-tax claims from payroll submission

Use [`GET /tax_credits`](/docs/api-reference/tax-credits/list-tax-credits) to discover your company's R\&D credits across tax years, and [`GET /tax_credits/{id}`](/docs/api-reference/tax-credits/retrieve-tax-credit) to retrieve one credit. Both require **API access: Manage** and **Taxes: View**, checked against the API key owner's current permissions. The credential selects the company; there is no company-ID parameter.

Each record represents one credit per **type, jurisdiction, and tax year**. Currently the API supports `research_and_development` credits in `US`, with `usd` amounts. Estimates, undecided years, and years where you declined credits are included so a caller can explain why a year has no claimed credit.

## Discovering credits

Omit `year` to discover all available years, newest first:

```bash theme={null}
curl "https://app.finta.com/api/v1/tax_credits" \
  -H "Authorization: Bearer finta_your_key_here"
```

Optional filters compose:

| Parameter | Values and behavior |
| - | - |
| `type` | Currently `research_and_development`. |
| `year` | Four-digit tax year, not the calendar year when filing or submission occurred. Omit for all available years. |
| `claim_status` | `undecided`, `not_claimed`, `pending`, or `claimed`. |
| `limit` | Page size, default 100, maximum 500. An omitted or empty value uses the default. |
| `starting_after` | Pass the previous page's `next_cursor` unchanged, with the same filters. |

```bash theme={null}
curl "https://app.finta.com/api/v1/tax_credits?type=research_and_development&year=2025&claim_status=claimed" \
  -H "Authorization: Bearer finta_your_key_here"
```

The list uses the standard [pagination envelope](/docs/api-reference/pagination). An initial query with no matching records returns `data: []`, `has_more: false`, and `next_cursor: null`. Empty `type`, `year`, and `claim_status` values are invalid; omit a filter to leave it unconstrained. There is no jurisdiction filter in this version.

If `has_more` is true, continue with `starting_after=next_cursor`. Pagination is live, not a snapshot. A credit whose claim status changes can stop matching your filters; an unavailable or filtered-out cursor returns `404 resource_missing` with `param: "starting_after"`. Restart from the first page with the desired filters.

## Example response

Synthetic values for `GET /tax_credits`:

```json theme={null}
{
  "object": "list",
  "url": "/api/v1/tax_credits",
  "has_more": false,
  "next_cursor": null,
  "data": [
    {
      "id": "tcred_example1",
      "object": "tax_credit",
      "type": "research_and_development",
      "jurisdiction": "US",
      "year": 2025,
      "claim_status": "claimed",
      "amount_cents": 2500000,
      "currency": "usd",
      "amount_basis": "filed_return",
      "applied_to_income_tax_cents": 500000,
      "payroll_credit_cents": 2000000,
      "payroll_submission": {
        "provider": "gusto",
        "status": "pending"
      },
      "created": 1769000000,
      "updated": 1791850000
    }
  ]
}
```

This is a **\$25,000 total credit**, with **\$5,000 applied against income tax** and **\$20,000 allocated to payroll**. It is included in the filed income-tax return, while the payroll submission is still pending.

<Note>
  A payroll credit allocation is not a refund received. Finta does not track provider acceptance or refunds received, and this API does not assert either.
</Note>

Retrieve that credit by passing its ID unchanged:

```bash theme={null}
curl "https://app.finta.com/api/v1/tax_credits/tcred_example1" \
  -H "Authorization: Bearer finta_your_key_here"
```

Retrieval returns the `tax_credit` object directly, without the list envelope. `tcred_` IDs remain stable for a company/type/jurisdiction/year even when the source questionnaire changes. If onboarding was restarted for a year, a filed return takes precedence; otherwise the latest-created questionnaire supplies the record.

All timestamps use Unix seconds. `created` is the source questionnaire's creation time; `updated` is the most recent change to that questionnaire, its income-tax filing, or its return package. Reads do not calculate credits, change claim decisions, file returns, or submit credits to payroll.

## Amounts and their source

All amounts are integer cents. Recorded return totals take precedence over estimates. A declined year may still show an estimate of its potential credit; that is not an amount claimed.

| Field | Meaning |
| - | - |
| `amount_cents` | Total credit before allocation, or `null` when unknown. |
| `applied_to_income_tax_cents` | Recorded allocation against income tax, or `null` when absent or inconsistent with the recorded return total. |
| `payroll_credit_cents` | Recorded return total less the income-tax allocation. `null` unless both are known and consistent. |
| `currency` | Currently `usd`. |

`amount_basis` explains where `amount_cents` came from:

| Value | Meaning |
| - | - |
| `estimate` | A recorded onboarding estimate, rather than a known return total. |
| `prepared_return` | A recorded return total before income-tax filing is complete. |
| `filed_return` | A recorded return total after income-tax filing is complete. |
| `null` | The amount is unknown. |

An unverified database-default zero does not establish a known amount. A zero return total with an explicit zero income-tax allocation establishes a known zero. Never convert a null amount to zero: `null` means unknown, while `0` means a known zero.

A filed income-tax workflow alone does not turn an estimate into a filed credit amount. If the return total is unknown, the API can retain the estimate and label it `estimate`. Payroll allocations can be available before filing, but only when the return total and income-tax allocation are known.

## Claim status

`claim_status` describes the decision and inclusion in the income-tax return:

| Value | Meaning |
| - | - |
| `undecided` | No claim decision is recorded. |
| `not_claimed` | You declined to claim credits. |
| `pending` | You opted in, but inclusion in a filed return is not yet established. |
| `claimed` | A positive credit is recorded in the filed income-tax return. |

An explicit decline takes precedence over other claim signals. Historical filed returns with positive recorded credits can be `claimed` without a saved opt-in. `claimed` says nothing about payroll submission, provider confirmation, or refunds received.

## Payroll submission

`payroll_submission` always contains `provider` and `status`. The provider is the recorded R\&D payroll selection, otherwise Gusto/Rippling detection or the sole recorded payroll provider. It is `null` when unresolved.

| Status | Meaning |
| - | - |
| `waiting_for_tax_filing` | You opted in and income tax is not yet filed. |
| `pending` | Income tax is filed with a positive credit and known positive payroll allocation; submission is still required and the provider is Gusto or Rippling. |
| `action_required` | The same filed credit and positive payroll allocation are recorded, but submission is still required and payroll uses an unsupported provider, or no payroll software is recorded. |
| `submitted` | The filed positive credit has a known positive payroll allocation, and Finta records an explicit payroll submission as complete. |
| `not_required` | Credits were declined, or the known payroll allocation is zero, including credits fully applied against income tax. |
| `unknown` | The recorded decision, amounts, allocation, provider, or submission state are insufficient to determine progress. |

Finta also marks the payroll task done automatically when credits are fully offset against income tax. A known zero payroll allocation therefore returns `not_required` even when that task is marked done. If staff later revises that offset or replaces the draft, an automatic completion remains distinct from an explicit submission. A newly positive payroll allocation can therefore return `pending` or `action_required` rather than `submitted`. Resaving the unchanged done field does not assert submission. Historical done flags without a known completion reason return `unknown` when payroll submission is required. A submission timestamp alone is insufficient because other state changes also set it.

`submitted` means recorded as submitted in Finta. It is not a provider acknowledgment, a guarantee of acceptance, or evidence of a refund. Treat future status values as unknown until you understand their documented meaning rather than inferring stronger guarantees.

## Errors

| Status | Code and behavior |
| - | - |
| `400` | `invalid_request`: invalid public ID, filter, or limit; `param` identifies the field. |
| `404` | `resource_missing`: missing or other-company credit, or a cursor absent from the filtered company list; `param` is `id` or `starting_after`. |
| `401` / `403` | Existing authentication, account, subscription, and live-permission errors apply. |
| `429` | Existing burst and monthly [usage limits](/docs/api-reference/usage-limits) apply. |

`submitted` is a payroll-submission status, not a claim status. This request is rejected:

```http theme={null}
GET /api/v1/tax_credits?claim_status=submitted HTTP/1.1
Authorization: Bearer finta_example

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_request",
    "message": "claim_status must be undecided, not_claimed, pending, or claimed.",
    "param": "claim_status",
    "doc_url": "https://www.finta.com/docs/api-reference/errors#invalid_request"
  }
}
```

IDs must be `tcred_` followed by a nonempty alphanumeric suffix. Numeric IDs and UUIDs are not accepted. A valid-format ID absent from the company produces this response, including when it belongs to another company:

```http theme={null}
GET /api/v1/tax_credits/tcred_absent HTTP/1.1
Authorization: Bearer finta_example

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_missing",
    "message": "Tax credit not found.",
    "param": "id",
    "doc_url": "https://www.finta.com/docs/api-reference/errors#resource_missing"
  }
}
```

Both reads count toward the normal API allowance. Successful responses and burst-limit rejections include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`; early authentication, authorization, and monthly-limit errors can omit them. Honor `Retry-After` on burst-limit rejections. Monthly-limit rejections do not send it and are not an immediate retry condition. See [Errors](/docs/api-reference/errors) for shared error codes and retry guidance.


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