docs: add API tokens and webhook ingestion documentation
Update API.md with API token management endpoints, usage examples, and authentication guide. Update UserGuide.md with webhook ingestion and API tokens sections. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
+12
-9
@@ -55,7 +55,7 @@ router = APIRouter()
|
||||
def get_current_user(request: Request):
|
||||
# Check for Bearer token auth first (API tokens)
|
||||
api_user = getattr(request.state, "api_token_user", None)
|
||||
if api_user:
|
||||
if isinstance(api_user, dict):
|
||||
return api_user
|
||||
return request.session.get("user")
|
||||
|
||||
@@ -71,11 +71,11 @@ def _resolve_bearer_user(request: Request, db: Session) -> dict | None:
|
||||
A user dict or ``None`` if no valid Bearer token is present.
|
||||
"""
|
||||
auth_header = request.headers.get("authorization", "")
|
||||
if not auth_header.startswith("Bearer "):
|
||||
if not isinstance(auth_header, str) or not auth_header.startswith("Bearer "):
|
||||
return None
|
||||
|
||||
raw_token = auth_header[7:]
|
||||
if not raw_token:
|
||||
if not raw_token or not isinstance(raw_token, str):
|
||||
return None
|
||||
|
||||
from app.models import ApiToken
|
||||
@@ -145,13 +145,16 @@ def require_login(func):
|
||||
# Fall back to Bearer token auth for API endpoints
|
||||
url_path = urlparse(str(request.url)).path
|
||||
if url_path.startswith("/api/"):
|
||||
from app.database import SessionLocal
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
api_user = _resolve_bearer_user(request, db)
|
||||
finally:
|
||||
db.close()
|
||||
from app.database import SessionLocal
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
api_user = _resolve_bearer_user(request, db)
|
||||
finally:
|
||||
db.close()
|
||||
except Exception:
|
||||
api_user = None
|
||||
|
||||
if api_user:
|
||||
request.state.api_token_user = api_user
|
||||
|
||||
+132
-1
@@ -86,7 +86,38 @@ def make_api_request(url, max_retries=3):
|
||||
|
||||
## Authentication
|
||||
|
||||
When authentication is enabled, you must include an authentication token in your requests:
|
||||
When authentication is enabled, you must include an authentication token in your requests.
|
||||
|
||||
### API Tokens (Recommended)
|
||||
|
||||
DocuElevate supports personal API tokens for programmatic access. Tokens are the recommended
|
||||
way to authenticate scripts, CI/CD pipelines, and webhook integrations.
|
||||
|
||||
**Creating a token:**
|
||||
|
||||
1. Log in to DocuElevate and navigate to **API Tokens** (available in your user menu or at `/api-tokens`).
|
||||
2. Enter a descriptive name (e.g. "CI Pipeline", "Scanner Integration") and click **Create Token**.
|
||||
3. Copy the token immediately — it is shown only once.
|
||||
|
||||
**Using a token:**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://<your-docuelevate-instance>/api/files" \
|
||||
-H "Authorization: Bearer <your-api-token>"
|
||||
```
|
||||
|
||||
**Managing tokens programmatically:**
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `POST` | `/api/api-tokens/` | Create a new token |
|
||||
| `GET` | `/api/api-tokens/` | List all your tokens |
|
||||
| `DELETE` | `/api/api-tokens/{id}` | Revoke a token |
|
||||
|
||||
### Session Authentication
|
||||
|
||||
Browser-based users authenticate via OAuth or local login. Session cookies are set
|
||||
automatically and used for subsequent requests:
|
||||
|
||||
```bash
|
||||
curl -X GET "http://<your-docuelevate-instance>/api/files" \
|
||||
@@ -1900,6 +1931,106 @@ Pass no `pipeline_id` query parameter (or omit it) to clear the assignment.
|
||||
```
|
||||
|
||||
|
||||
## API Tokens
|
||||
|
||||
Personal API tokens allow programmatic access to the DocuElevate API without
|
||||
session cookies. Tokens are ideal for CI/CD pipelines, webhook integrations,
|
||||
and automation scripts.
|
||||
|
||||
Each token is prefixed with `de_` for easy identification. Only a SHA-256 hash
|
||||
is stored server-side; the plaintext is returned exactly once at creation time.
|
||||
|
||||
Usage tracking records when each token was last used and from which IP address.
|
||||
|
||||
### POST /api/api-tokens/
|
||||
|
||||
Create a new API token.
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"name": "CI Pipeline"
|
||||
}
|
||||
```
|
||||
|
||||
**Response (201 Created):**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "CI Pipeline",
|
||||
"token_prefix": "de_Ab3xY7kL",
|
||||
"token": "de_Ab3xY7kLmN9pQrStUvWxYz0123456789abcdef",
|
||||
"is_active": true,
|
||||
"last_used_at": null,
|
||||
"last_used_ip": null,
|
||||
"created_at": "2026-03-08T12:00:00Z",
|
||||
"revoked_at": null
|
||||
}
|
||||
```
|
||||
|
||||
> **Important:** The `token` field is only included in the creation response.
|
||||
> Copy it immediately — it will not be shown again.
|
||||
|
||||
### GET /api/api-tokens/
|
||||
|
||||
List all tokens for the authenticated user. The full token value is never included.
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "CI Pipeline",
|
||||
"token_prefix": "de_Ab3xY7kL",
|
||||
"is_active": true,
|
||||
"last_used_at": "2026-03-08T15:30:00Z",
|
||||
"last_used_ip": "203.0.113.42",
|
||||
"created_at": "2026-03-08T12:00:00Z",
|
||||
"revoked_at": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### DELETE /api/api-tokens/{token_id}
|
||||
|
||||
Revoke a token. The token is soft-deleted (kept for audit purposes) and can no
|
||||
longer be used for authentication.
|
||||
|
||||
**Response (200):**
|
||||
```json
|
||||
{
|
||||
"detail": "Token revoked"
|
||||
}
|
||||
```
|
||||
|
||||
### Using API Tokens
|
||||
|
||||
Include the token in the `Authorization` header of any API request:
|
||||
|
||||
```bash
|
||||
# Upload a document
|
||||
curl -X POST "http://your-instance/api/files/ui-upload" \
|
||||
-H "Authorization: Bearer de_your_token_here" \
|
||||
-F "file=@/path/to/document.pdf"
|
||||
|
||||
# List files
|
||||
curl -X GET "http://your-instance/api/files" \
|
||||
-H "Authorization: Bearer de_your_token_here"
|
||||
```
|
||||
|
||||
**Python example:**
|
||||
```python
|
||||
import requests
|
||||
|
||||
response = requests.post(
|
||||
"http://your-instance/api/files/ui-upload",
|
||||
headers={"Authorization": "Bearer de_your_token_here"},
|
||||
files={"file": open("document.pdf", "rb")},
|
||||
)
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
|
||||
## Further Assistance
|
||||
|
||||
For additional help with the API, please contact our support team or refer to the [Development Guide](../CONTRIBUTING.md).
|
||||
|
||||
@@ -165,6 +165,7 @@ The **Integrations** page (`/integrations`) provides a unified view of all your
|
||||
- **Email Forward** — recipient email address
|
||||
- **Watch Folder** — folder path
|
||||
- **Paperless NGX** — URL and API token
|
||||
- **Webhook** — no configuration needed; the form shows a quick-start guide with sample `curl` and Python snippets for uploading documents via the API
|
||||
5. Click **Test Connection** to verify the settings before saving.
|
||||
6. Click **Save** to persist the integration.
|
||||
|
||||
@@ -193,6 +194,52 @@ DocuElevate can poll an FTP or SFTP directory for new files. Enable this with `F
|
||||
|
||||
See [Configuration Guide — Watch Folder Ingestion](ConfigurationGuide.md#watch-folder-ingestion) for full setup instructions.
|
||||
|
||||
### Webhook Ingestion (API Upload)
|
||||
|
||||
Webhook integrations allow external systems to push documents directly into DocuElevate
|
||||
via the REST API. Instead of DocuElevate polling for new files, **your application sends
|
||||
files to DocuElevate** using an HTTP request with an API token for authentication.
|
||||
|
||||
This is ideal for:
|
||||
- **CI/CD pipelines** — upload build artifacts or generated reports
|
||||
- **Scanner integrations** — push scanned documents from network scanners
|
||||
- **Automation scripts** — send documents from any system with HTTP support
|
||||
|
||||
To set up webhook ingestion:
|
||||
|
||||
1. Go to **Integrations** and add a new **Source → Webhook** integration.
|
||||
The integration form shows copy-ready code snippets.
|
||||
2. Go to **API Tokens** (in your user menu) and create a personal API token.
|
||||
3. Use the token to upload documents:
|
||||
|
||||
```bash
|
||||
curl -X POST "https://your-instance/api/files/ui-upload" \
|
||||
-H "Authorization: Bearer de_your_token_here" \
|
||||
-F "file=@/path/to/document.pdf"
|
||||
```
|
||||
|
||||
See the [API Documentation](API.md#api-tokens) for detailed API token management.
|
||||
|
||||
### API Tokens
|
||||
|
||||
API tokens provide secure, programmatic access to the DocuElevate API. Each user
|
||||
can create multiple tokens, each with a descriptive name.
|
||||
|
||||
**Features:**
|
||||
- **Multiple tokens** — create separate tokens for different scripts or integrations
|
||||
- **Usage tracking** — see when each token was last used and from which IP address
|
||||
- **Revocation** — instantly disable a compromised token without affecting others
|
||||
|
||||
**Managing tokens:**
|
||||
|
||||
1. Click your avatar in the top navigation and select **API Tokens**, or go to `/api-tokens`.
|
||||
2. Enter a descriptive name and click **Create Token**.
|
||||
3. Copy the token immediately — it is shown only once.
|
||||
4. To revoke a token, click **Revoke** next to it in the token list.
|
||||
|
||||
> **Security tip:** Create a dedicated token for each integration and revoke it
|
||||
> immediately if compromised. Never share tokens or commit them to source control.
|
||||
|
||||
## Managing Documents
|
||||
|
||||
The **Files** page provides access to all processed documents:
|
||||
|
||||
Reference in New Issue
Block a user