API Endpoints

This document provides a detailed reference for all available TextWatermark API v2 endpoints. All requests and responses are in JSON format. The base URL for all API v2 endpoints is: https://api.textwatermark.com

User Authentication & Management

These endpoints manage user registration, login, and profiles. They typically require JWT authentication obtained via the login endpoint. See the Authentication Guide for more details.

Register User

POST /api/v2/users/register

Creates a new user profile and associated authentication credentials.

Request Body:

{
  "email": "[email protected]",
  "password": "YourStrongPassword123!",
  "username": "newuser",
  "firstName": "Test",
  "lastName": "User"
}

Successful Response (201 Created):

{
  "message": "User registered successfully. Please check your email to verify your account.",
  "user": {
    "id": "user_uuid",
    "email": "[email protected]",
    "username": "newuser",
    // ... other user fields
  }
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/users/register \
     -H "Content-Type: application/json" \
     -d '{
           "email": "[email protected]", 
           "password": "Password123!", 
           "username": "testuser", 
           "firstName": "Test", 
           "lastName": "User"
         }'

Login User

POST /api/v2/users/login

Authenticates a user and returns a session, including a JWT access token.

Request Body:

{
  "email": "[email protected]",
  "password": "YourStrongPassword123!"
}

Successful Response (200 OK):

{
  "message": "Login successful",
  "access_token": "your_jwt_access_token",
  "refresh_token": "your_jwt_refresh_token",
  "expires_in": 3600,
  "user": {
    "id": "user_uuid",
    "email": "[email protected]",
    // ... other user fields
  }
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/users/login \
     -H "Content-Type: application/json" \
     -d '{"email": "[email protected]", "password": "Password123!"}'

Get User Profile

GET /api/v2/users/me

Fetches the profile, API tokens, and quota for the currently authenticated user. Requires JWT authentication.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Successful Response (200 OK):

{
  "user": {
    "id": "user_uuid",
    "email": "[email protected]",
    "username": "testuser",
    // ... other profile fields
  },
  "api_tokens": [
    // ... list of user's API tokens (excluding raw token)
  ],
  "quota": {
    // ... user's quota information
  }
}

Example cURL:

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/users/me

Update User Profile

PUT /api/v2/users/me

Updates the profile information (e.g., name, username) for the currently authenticated user. Requires JWT authentication.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Request Body: (Include only fields to update)

{
  "username": "updated_username",
  "firstName": "UpdatedFirstName",
  "lastName": "UpdatedLastName"
}

Successful Response (200 OK):

{
  "message": "Profile updated successfully.",
  "user": {
    "id": "user_uuid",
    "username": "updated_username",
    "firstName": "UpdatedFirstName",
    "lastName": "UpdatedLastName",
    // ... other updated fields
  }
}

Example cURL:

curl -X PUT https://api.textwatermark.com/api/v2/users/me \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"username": "updated_username", "firstName": "UpdatedName"}'

Change Password

PUT /api/v2/users/password

Allows the currently authenticated user to change their password. Requires JWT authentication.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Request Body:

{
  "currentPassword": "OldPassword123!",
  "newPassword": "NewStrongPassword456?"
}

Successful Response (200 OK):

{
  "message": "Password updated successfully."
}

Example cURL:

curl -X PUT https://api.textwatermark.com/api/v2/users/password \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"currentPassword": "OldPassword123!", "newPassword": "NewPassword456?"}'

API Token Management

These endpoints allow users to manage their API tokens for programmatic access to the TextWatermark API. All token management endpoints require JWT authentication obtained via the login endpoint. See the Authentication Guide for more details.

List API Tokens

GET /api/v2/users/tokens

Retrieves a list of all API tokens associated with the authenticated user's account. The full token values are not returned for security reasons.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Successful Response (200 OK):

{
  "tokens": [
    {
      "id": "token_uuid_1",
      "name": "My Web App Token",
      "token_prefix": "twk_AbCd...",
      "scopes": ["read:watermark", "write:watermark"],
      "created_at": "2023-10-26T10:00:00Z",
      "last_used_at": "2023-10-27T12:30:00Z"
    },
    {
      "id": "token_uuid_2",
      "name": "Analytics Script Token",
      "token_prefix": "twk_EfGh...",
      "scopes": ["read:watermark"],
      "created_at": "2023-09-15T08:00:00Z",
      "last_used_at": null
    }
  ]
}

Example cURL:

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/users/tokens

Create API Token

POST /api/v2/tokens

Creates a new API token. The generated token is returned in the response and should be stored securely as it will not be retrievable again.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Request Body:

{
  "name": "My New Integration Token",
  "permissions": ["read:watermark", "write:watermark"]
}

Successful Response (201 Created):

{
  "id": "new_token_uuid",
  "name": "My New Integration Token",
  "token": "twk_GeneratedFullApiTokenValueString", // Store this securely!
  "token_prefix": "twk_Gene...", 
  "permissions": ["read:watermark", "write:watermark"],
  "created_at": "2023-10-28T14:00:00Z"
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/tokens \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{
           "name": "My New Integration Token",
           "permissions": ["read:watermark", "write:watermark"]
         }'

Update API Token

PUT /api/v2/users/tokens/{tokenId}

Updates the properties of an existing API token, such as its name or assigned permissions. (Note: This endpoint was not explicitly in the provided OpenAPI summary; verify its existence if OpenAPI is strict ground truth.)

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • tokenId (string, required): The ID of the token to update.

Request Body: (Include only fields to update)

{
  "name": "Updated Token Name",
  "permissions": ["read:watermark"]
}

Successful Response (200 OK):

{
  "id": "token_uuid_1",
  "name": "Updated Token Name",
  "token_prefix": "twk_AbCd...",
  "permissions": ["read:watermark"],
  "created_at": "2023-10-26T10:00:00Z",
  "last_used_at": "2023-10-27T12:30:00Z"
}

Example cURL:

curl -X PUT https://api.textwatermark.com/api/v2/users/tokens/token_uuid_1 \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"name": "Updated Token Name", "permissions": ["read:watermark"]}'

Delete API Token

DELETE /api/v2/users/tokens/{tokenId}

Revokes and permanently deletes an API token. This action cannot be undone.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • tokenId (string, required): The ID of the token to delete.

Successful Response (204 No Content or 200 OK with message):

// HTTP 204 No Content (preferred)
// OR
{
  "message": "API token revoked successfully."
}

Example cURL:

curl -X DELETE https://api.textwatermark.com/api/v2/users/tokens/token_uuid_1 \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>"

Watermarking Operations

These are the core endpoints for embedding (encoding) and extracting (decoding) watermarks within text. These operations typically require authentication via an API Key passed in the X-API-Key header.

Encode Watermark

POST /api/v2/watermark/encode

Embeds a hidden payload (watermark) into the provided text using the specified algorithm. The Unicode Variation Selector method is commonly used for its subtlety.

Headers: X-API-Key: <YOUR_API_KEY>

Request Body:

{
  "text": "This is the original document text that needs to be watermarked.",
  "payload": "Confidential: Project Alpha Details",
  "algorithm": "unicode_variation_selector_v1", // Optional, defaults to a recommended algorithm
  "strength": "medium" // Optional: 'low', 'medium', 'high' - influences visibility vs. robustness
}

Successful Response (200 OK):

{
  "watermarked_text": "This i︀s th︁e ori︂ginal do︃cument te︄xt tha︅t nee︆ds to ︇be wa︈termar︉ked.", // Example with invisible chars
  "original_text_length": 68,
  "watermarked_text_length": 77, // Length increases due to watermark characters
  "payload_length": 33,
  "algorithm_used": "unicode_variation_selector_v1",
  "estimated_robustness": "medium"
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/watermark/encode \
     -H "X-API-Key: <YOUR_API_KEY>" \
     -H "Content-Type: application/json" \
     -d '{
           "text": "This is the original document text that needs to be watermarked.",
           "payload": "Confidential: Project Alpha Details",
           "algorithm": "unicode_variation_selector_v1"
         }'

Decode Watermark

POST /api/v2/watermark/decode

Attempts to extract a hidden payload from the provided text. The system may try to auto-detect the algorithm if not specified.

Headers: X-API-Key: <YOUR_API_KEY>

Request Body:

{
  "watermarked_text": "This i︀s th︁e ori︂ginal do︃cument te︄xt tha︅t nee︆ds to ︇be wa︈termar︉ked.",
  "algorithm": "unicode_variation_selector_v1" // Optional
}

Successful Response (200 OK - Watermark Found):

{
  "payload": "Confidential: Project Alpha Details",
  "algorithm_detected": "unicode_variation_selector_v1",
  "confidence_score": 0.98 // A score indicating the likelihood of a correct decode
}

Successful Response (200 OK - No Watermark Found):

{
  "payload": null,
  "message": "No watermark detected or payload could not be reliably extracted.",
  "algorithm_detected": null,
  "confidence_score": 0.05
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/watermark/decode \
     -H "X-API-Key: <YOUR_API_KEY>" \
     -H "Content-Type: application/json" \
     -d '{"watermarked_text": "Text possibly containing a watermark..."}'

Analyze Text for Watermarks

POST /api/v2/watermark/analyze

Inspects the provided text for characteristics of known watermarking algorithms and provides an analysis, without attempting a full decode.

Headers: X-API-Key: <YOUR_API_KEY>

Request Body:

{
  "text": "Some text that might or might not contain a watermark."
}

Successful Response (200 OK):

{
  "analysis": {
    "has_potential_watermark": true,
    "detected_algorithms": [
      {
        "name": "unicode_variation_selector_v1",
        "confidence": 0.85,
        "estimated_payload_length_range": [20, 40] // characters
      }
    ],
    "text_characteristics": {
      "length": 55,
      "non_ascii_character_count": 9
    }
  }
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/watermark/analyze \
     -H "X-API-Key: <YOUR_API_KEY>" \
     -H "Content-Type: application/json" \
     -d '{"text": "Analyzing this sample text for hidden marks."}'

Quota Management

This section outlines how to check your current API usage against your allocated quotas. Quotas are typically based on your subscription plan and are reset periodically (e.g., monthly).

Get Quota Status

GET /api/v2/quota

Retrieves the current API usage and limits for the authenticated user. This helps in monitoring your consumption of resources like encode/decode operations or total characters processed.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN> OR X-API-Key: <YOUR_API_KEY> (if quota is tied to a specific API key)

Successful Response (200 OK):

{
  "plan_name": "Pro Plan",
  "quota_period_start": "2023-11-01T00:00:00Z",
  "quota_period_end": "2023-11-30T23:59:59Z",
  "quotas": {
    "encode_operations": {
      "limit": 10000,
      "used": 4520,
      "remaining": 5480
    },
    "decode_operations": {
      "limit": 50000,
      "used": 12340,
      "remaining": 37660
    },
    "analyze_operations": {
      "limit": 20000,
      "used": 500,
      "remaining": 19500
    },
    "characters_processed": {
      "limit": 10000000, // e.g., 10 million characters
      "used": 2500000,
      "remaining": 7500000
    }
  },
  "message": "Quota status retrieved successfully."
}

Example cURL (using JWT):

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/quota

Example cURL (using API Key):

curl -H "X-API-Key: <YOUR_API_KEY>" \
     https://api.textwatermark.com/api/v2/quota

Webhook Management

Webhooks allow your application to receive real-time HTTP notifications when specific events occur within the TextWatermark system. Instead of polling the API for changes, you can subscribe to events and have TextWatermark send a POST request to your specified URL when those events happen.

Common use cases include notifications for asynchronous job completion, quota warnings, or changes to your account. All webhook management endpoints require JWT authentication. It is highly recommended to use a secret when creating webhooks to verify the authenticity of incoming payloads.

List Webhooks

GET /api/v2/webhooks

Retrieves a list of all webhooks configured for the authenticated user's account.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Successful Response (200 OK):

{
  "webhooks": [
    {
      "id": "wh_uuid_1",
      "url": "https://myapp.com/webhooks/textwatermark",
      "subscribed_events": ["encode.success", "quota.warning"],
      "status": "active",
      "created_at": "2023-11-10T10:00:00Z",
      "last_delivery_at": "2023-11-15T12:30:00Z",
      "last_delivery_status": "success"
    },
    {
      "id": "wh_uuid_2",
      "url": "https://anotherapp.com/notifications",
      "subscribed_events": ["decode.failed"],
      "status": "inactive",
      "created_at": "2023-10-05T08:00:00Z",
      "last_delivery_at": null,
      "last_delivery_status": null
    }
  ]
}

Example cURL:

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/webhooks

Create Webhook

POST /api/v2/webhooks

Registers a new webhook endpoint to receive notifications for specified events.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Request Body:

{
  "url": "https://myapp.com/webhooks/textwatermark-notifications",
  "subscribed_events": ["encode.success", "encode.failed", "quota.limit.exceeded"],
  "secret": "your_secure_random_string_for_signature_verification", // Optional, but highly recommended
  "description": "Notifications for my primary application" // Optional
}

Successful Response (201 Created):

{
  "id": "wh_new_uuid",
  "url": "https://myapp.com/webhooks/textwatermark-notifications",
  "subscribed_events": ["encode.success", "encode.failed", "quota.limit.exceeded"],
  "status": "active", // Webhooks are typically active by default
  "has_secret": true,
  "description": "Notifications for my primary application",
  "created_at": "2023-11-16T14:00:00Z"
}

Note on secret: If a secret is provided, TextWatermark will sign webhook event payloads. The signature will be included in the X-Webhook-Signature header (e.g., using HMAC-SHA256). You should verify this signature on your server to ensure the payload is genuine.

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/webhooks \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{
           "url": "https://myapp.com/webhooks/textwatermark-notifications",
           "subscribed_events": ["encode.success", "quota.limit.exceeded"],
           "secret": "s3cr3t_k3y_v4lu3"
         }'

Get Webhook Details

GET /api/v2/webhooks/{webhookId}

Retrieves the details of a specific webhook by its ID.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • webhookId (string, required): The ID of the webhook to retrieve.

Successful Response (200 OK):

{
  "id": "wh_uuid_1",
  "url": "https://myapp.com/webhooks/textwatermark",
  "subscribed_events": ["encode.success", "quota.warning"],
  "status": "active",
  "has_secret": true,
  "description": "Production webhook",
  "created_at": "2023-11-10T10:00:00Z",
  "updated_at": "2023-11-12T11:00:00Z"
}

Example cURL:

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/webhooks/wh_uuid_1

Update Webhook

PUT /api/v2/webhooks/{webhookId}

Updates the configuration of an existing webhook. You can change the URL, subscribed events, secret, or status.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • webhookId (string, required): The ID of the webhook to update.

Request Body: (Include only fields to update)

{
  "url": "https://new-app-url.com/webhooks/listener",
  "subscribed_events": ["decode.success"],
  "status": "inactive", // e.g., to temporarily disable the webhook
  "secret": "new_secure_secret_optional" // To update or set a secret
}

Successful Response (200 OK):

{
  "id": "wh_uuid_1",
  "url": "https://new-app-url.com/webhooks/listener",
  "subscribed_events": ["decode.success"],
  "status": "inactive",
  "has_secret": true, // Will be true if a secret is set or updated
  "description": "Production webhook", // Unchanged fields remain
  "created_at": "2023-11-10T10:00:00Z",
  "updated_at": "2023-11-16T15:30:00Z"
}

Example cURL:

curl -X PUT https://api.textwatermark.com/api/v2/webhooks/wh_uuid_1 \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"url": "https://new-app-url.com/webhooks/listener", "status": "inactive"}'

Delete Webhook

DELETE /api/v2/webhooks/{webhookId}

Permanently removes a webhook configuration. This action cannot be undone.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • webhookId (string, required): The ID of the webhook to delete.

Successful Response (204 No Content or 200 OK with message):

// HTTP 204 No Content (preferred for DELETE operations)
// OR (if providing a message):
{
  "message": "Webhook wh_uuid_1 deleted successfully."
}

Example cURL:

curl -X DELETE https://api.textwatermark.com/api/v2/webhooks/wh_uuid_1 \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>"

List Webhook Deliveries

GET /api/v2/webhooks/{webhookId}/deliveries

Retrieves a log of recent event delivery attempts for a specific webhook. This is useful for diagnostics and troubleshooting failed deliveries.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • webhookId (string, required): The ID of the webhook.

Successful Response (200 OK):

{
  "deliveries": [
    {
      "id": "delivery_uuid_1",
      "event_type": "encode.success",
      "status": "success",
      "timestamp": "2023-11-15T12:30:00Z",
      "response_status_code": 200
    },
    {
      "id": "delivery_uuid_2",
      "event_type": "quota.warning",
      "status": "failed",
      "timestamp": "2023-11-14T10:15:00Z",
      "response_status_code": 503,
      "error_message": "Remote server unavailable"
    }
  ],
  "pagination": {
    "next_cursor": "cursor_string_for_next_page",
    "has_more": true
  }
}

Example cURL:

curl -H "Authorization: Bearer <JWT_ACCESS_TOKEN>" \
     https://api.textwatermark.com/api/v2/webhooks/wh_uuid_1/deliveries

Redeliver Webhook Event

POST /api/v2/webhooks/deliveries/{deliveryId}/redeliver

Attempts to resend a specific webhook event notification that previously failed or was not received.

Headers: Authorization: Bearer <JWT_ACCESS_TOKEN>

Path Parameters:

  • deliveryId (string, required): The ID of the delivery attempt to redeliver.

Successful Response (202 Accepted or 200 OK):

{
  "message": "Webhook event redelivery queued.",
  "redelivery_attempt_id": "redelivery_uuid_new"
}

Example cURL:

curl -X POST https://api.textwatermark.com/api/v2/webhooks/deliveries/delivery_uuid_2/redeliver \
     -H "Authorization: Bearer <JWT_ACCESS_TOKEN>"