> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usefini.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Register provider resources
> Create or update source records from provider resources. Step 2 of the connected-source flow.
Creates or updates source records for the resources you discovered with [List provider resources](/en/api-reference/list-provider-resources), and returns the resulting source IDs in the wire-format fields `addedDocumentIds` and `updatedDocumentIds`.
<Warning>
This route does **not** queue ingestion by itself. It only creates source records. To actually start processing, call [Ingest sources](/en/api-reference/ingest-sources) next, passing the IDs returned by this route.
</Warning>
## Headers
<ParamField header="Authorization" type="string" required>
Bearer token containing your Fini workspace API key. Format: `Bearer fini_...` The key needs `write` scope.
</ParamField>
<ParamField header="Content-Type" type="string" required>
`application/json`
</ParamField>
## Path parameters
<ParamField path="provider" type="string" required>
Provider name. Supported values: `notion`, `zendesk`, `confluence`. Must match a provider that's already connected in the workspace.
</ParamField>
## Body parameters
<ParamField body="resources" type="array" required>
Array of resource objects to register. Each resource accepts the fields below.
<Expandable title="resource object">
<ParamField body="originalUrl" type="string" required>
Provider URL for the resource.
</ParamField>
<ParamField body="title" type="string" required>
Resource title.
</ParamField>
<ParamField body="externalId" type="string" required>
Provider-specific identifier (e.g., the Notion page ID).
</ParamField>
<ParamField body="mimeType" type="string" required>
Resource MIME type. Typically taken from the discovery response.
</ParamField>
<ParamField body="storageUrl" type="string">
Optional internal storage URL.
</ParamField>
<ParamField body="object" type="string">
Optional provider-specific type (e.g., Notion `object: "page"`).
</ParamField>
</Expandable>
</ParamField>
<RequestExample>
~~~bash cURL theme={null}
curl --request POST \
--url 'https://api-prod.usefini.com/v2/documents/public/resources/notion' \
--header 'Authorization: Bearer fini_your_api_key' \
--header 'Content-Type: application/json' \
--data '{
"resources": [
{
"originalUrl": "https://www.notion.so/fini/Billing-FAQ-123456",
"title": "Billing FAQ",
"externalId": "123456",
"mimeType": "text/markdown",
"object": "page"
}
]
}'
~~~
~~~python Python theme={null}
import requests
response = requests.post(
"https://api-prod.usefini.com/v2/documents/public/resources/notion",
headers={
"Authorization": "Bearer fini_your_api_key",
"Content-Type": "application/json",
},
json={
"resources": [
{
"originalUrl": "https://www.notion.so/fini/Billing-FAQ-123456",
"title": "Billing FAQ",
"externalId": "123456",
"mimeType": "text/markdown",
"object": "page",
}
]
},
)
data = response.json()
~~~
~~~javascript Node.js theme={null}
const response = await fetch(
"https://api-prod.usefini.com/v2/documents/public/resources/notion",
{
method: "POST",
headers: {
Authorization: "Bearer fini_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
resources: [
{
originalUrl: "https://www.notion.so/fini/Billing-FAQ-123456",
title: "Billing FAQ",
externalId: "123456",
mimeType: "text/markdown",
object: "page",
},
],
}),
}
);
const data = await response.json();
~~~
</RequestExample>
## Response
<ResponseField name="addedDocumentIds" type="array">
Source IDs for resources that were newly registered.
</ResponseField>
<ResponseField name="updatedDocumentIds" type="array">
Source IDs for resources that already existed in the workspace and had their metadata updated.
</ResponseField>
<ResponseExample>
~~~json 200 OK theme={null}
{
"provider": "notion",
"resources": [
{
"id": "page_123",
"title": "Refund policy",
"type": "page",
"path": "Policies / Refund policy"
}
]
}
~~~
</ResponseExample>
## Next step
Pass the returned `addedDocumentIds` and `updatedDocumentIds` into [Ingest sources](/en/api-reference/ingest-sources):
* Put new IDs into `documentIdsToAdd` to ingest them for the first time.
* Put existing IDs into `documentIdsToRefresh` to re-process them.
Without that follow-up call, the source records exist but no content gets processed.
## Errors
<AccordionGroup>
<Accordion title="400 Bad Request" icon="circle-exclamation">
The provider is not supported on the public route, not connected in the workspace, or one of the resource objects is missing required fields (`originalUrl`, `title`, `externalId`, `mimeType`).
</Accordion>
<Accordion title="401 Unauthorized" icon="lock">
The API key is missing, malformed, revoked, or invalid. Confirm `Authorization: Bearer fini_...` with the full key.
</Accordion>
<Accordion title="403 Forbidden" icon="shield-halved">
The API key doesn't include the `write` scope, or it's scoped to a different workspace.
</Accordion>
<Accordion title="The response returned IDs but nothing is processing" icon="circle-question">
Expected. This route only creates source records. It doesn't queue ingestion. Call [Ingest sources](/en/api-reference/ingest-sources) with the returned IDs to start processing.
</Accordion>
</AccordionGroup>
## Related topics
- [List provider resources](/en/api-reference/list-provider-resources.md)
- [Overview](/en/api-reference/sources.md)
- [Ingest sources](/en/api-reference/ingest-sources.md)
This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.
Sources

