Skip to API documentation

Developer documentation REST API v1

Natural writing.
One API.

Bring clearer, more natural text into your application. Choose a writing style, keep your meaning, and get a complete rewrite with transparent word-based credits.

POST /api/v1/humanizeJSON
{
    "text": "Clear writing helps readers understand.",
    "mode": "professional",
    "strength": "medium"
}
Your words, rewritten. One credit per input word.

A familiar request. A complete result.

The API uses HTTPS, bearer authentication and JSON. Keep your key on your server, choose a unique idempotency key, and send the text you want to improve.

  1. 01 / ACCOUNTPrepare your accountVerify your email and review the API plan and available credits.
  2. 02 / CREDENTIALCreate a private keySave the key when it is shown once. Keep it in your server environment.
  3. 03 / REQUESTSend your first rewriteStart with a short paragraph. Review the returned text before using it.

cURL · server terminal

curl https://www.convertfoto.com/api/v1/humanize \
  --header "Authorization: Bearer $CONVERTFOTO_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: example-document-0001" \
  --data '{"text":"Clear writing helps readers understand.",
           "mode":"professional","strength":"medium"}'

JavaScript · server only

const response = await fetch(
  'https://www.convertfoto.com/api/v1/humanize',
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.CONVERTFOTO_API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': 'example-document-0001'
    },
    body: JSON.stringify({
      text: 'Clear writing helps readers understand.',
      mode: 'professional',
      strength: 'medium'
    })
  }
);
const payload = await response.json();
if (!response.ok) throw new Error(payload.error.code);
console.log(payload.data.humanized_text);

PHP · server only

$request = curl_init('https://www.convertfoto.com/api/v1/humanize');
curl_setopt_array($request, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 240,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CONVERTFOTO_API_KEY'),
        'Content-Type: application/json',
        'Idempotency-Key: example-document-0001',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'text' => 'Clear writing helps readers understand.',
        'mode' => 'professional',
        'strength' => 'medium',
    ], JSON_THROW_ON_ERROR),
]);
$body = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
if ($body === false) throw new RuntimeException('Request unconfirmed');
$payload = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status !== 200) throw new RuntimeException($payload['error']['code']);
echo $payload['data']['humanized_text'];

Use these examples from a trusted server. Never embed an API key in browser JavaScript, a public repository, analytics or a request URL. Replace the example idempotency value for each new document.

Your key belongs on your server.

Create, revoke or regenerate a key in your account. Creation requires a verified active account. A key does not itself activate an API subscription or add credits. A regenerated key replaces the old key immediately.

Required authorization header

Authorization: Bearer YOUR_PRIVATE_API_KEY

Keys are shown in full once. The service stores a keyed digest and a public prefix, so a lost key must be regenerated. Revoked keys and keys invalidated by a password reset cannot authenticate. API calls use bearer credentials; they do not use website cookies.

A key has the format hz_key_<16 hex selector>_<64 hex secret>, using lowercase hexadecimal characters. Each account can hold up to ten active keys.

Keep the meaning. Choose the style.

Send text with optional mode and strength. The default is Standard mode with Medium strength. Humanize and paraphrase requests share the same credit and complete-result guarantees.

ParameterValuesPurpose
textUTF-8 string, requiredThe original text. Document and plan limits apply.
modestandard, casual, academic, professional, creativeThe writing style to preserve throughout the document.
strengthlight, medium, strongHow extensively to revise the wording.

Every successful synchronous response contains the complete rewritten text, authoritative input/output word counts, credits used and remaining available credits. The output is plain text; treat it as untrusted text when displaying it in HTML.

200 OK · illustrative complete result

{
    "success": true,
    "data": {
        "request_id": "aabbccddeeff0011223344556677889900",
        "humanized_text": "Better writing helps readers understand.",
        "original_words": 5,
        "rewritten_words": 5,
        "word_count_version": "unicode-runs-cjk-v1"
    },
    "usage": {
        "credits_used": 5,
        "remaining_credits": 19995
    }
}

Paragraphs, lists, factual markers and reasonable length are validated. Review the result for meaning and accuracy before publishing. Rewriting is intended to improve clarity and tone; no AI-detector evasion is promised.

Longer documents, without partial results.

Use POST /api/v1/jobs with the same text/options and an idempotency key for asynchronous work. A queued request reserves its input-word credits before returning 202 Accepted. Poll GET /api/v1/jobs/{id} with your bearer key.

Job statusMeaning
queuedAccepted and waiting for a worker. No partial text is available.
processingThe complete document is being processed sequentially.
succeededThe complete result and settled credit usage are available.
failedNo complete result was delivered. The reservation is released.

Poll at a modest interval and respect rate-limit headers. Queued text is encrypted and expires after 24 hours if it has not started. Completed output is available for 24 hours after completion; expired queued text or result retrieval returns 410. Scheduled cleanup removes expired ciphertext, while accounting and idempotency metadata remain.

A worker that loses its lease is not automatically restarted against the provider. Recovery reconciles a durable complete result or releases the reservation. Prompt and provider configuration are fixed when processing begins. No endpoint returns a document with failed or missing chunks.

Word-based credits. Server-enforced limits.

One credit equals one input word. The server normalizes and counts text using the reported word_count_version; client counts are estimates. Rewriting the same text as a new request uses credits again.

Website and API products share one wallet, with separate product entitlements. Monthly credits expire at period end; purchased top-ups do not expire. Credits are reserved before processing and deducted only when a complete result is saved. Failed work releases its reservation, while upstream provider costs are tracked separately.

A refunded payment can place new writing on hold if its credits have already been spent. billing_refund_hold returns HTTP 402 for new work; previously completed results remain retrievable within their retention period. New top-ups may first recover that credit shortfall. Hosted checkout redirects alone do not grant credits: verified payment events update the account. Review purchases, refunds and subscriptions in Plans and credits.

Read /account and /models for the account and supported capabilities. Document, rate and concurrent-job limits depend on the configured API plan. Synchronous processing also has a deployment cap; use jobs when a document requires asynchronous processing.

Response headerMeaning
X-RateLimit-LimitAllowed authenticated requests in the current window.
X-RateLimit-RemainingRequests remaining in that window.
X-RateLimit-ResetWindow reset as a Unix timestamp in seconds.
Retry-AfterSeconds to wait after a rate-limit response or before polling a pending submission.

Retry the request identity, not the charge.

Every generation or job POST requires Idempotency-Key: 16–128 characters using letters, digits, dots, underscores, colons or hyphens. Save the key with your own request record before sending it. Reuse that same key and identical text/options on the same endpoint when resolving a lost response; never switch to a fresh key simply because a request timed out. Reusing the key on a different endpoint starts a distinct billable operation.

Duplicate completed requests return the saved result without another generation or charge for 24 hours after completion. Replays remain available when new AI or queue processing is disabled, provided the API itself remains enabled. Changed content for an existing key returns a conflict. Failed or expired request identities remain closed and cannot restart processing. A timeout does not prove that the server or provider stopped working.

HTTP statusTypical action
400 / 422Correct the request shape, options or missing idempotency key.
401 / 403Check the key, verified account and API entitlement.
402Insufficient credits or billing_refund_hold; new processing was not admitted. Review the account balance and billing status.
404The route or account-owned job was not found.
409The request is still resolving, already failed, or conflicts with prior content.
410Queued input or the temporary result has expired; the request will not run again.
413 / 415Check document limits or use application/json.
429Wait for the documented rate/concurrency limit.
503Service unavailable or completion unconfirmed. Preserve the original idempotency key and check the account/job state.

Consistent error envelope

{
  "success": false,
  "error": {
    "code": "insufficient_credits",
    "message": "There are not enough available credits."
  }
}

Endpoint reference

All protected routes use the base path /api/v1. The list below is generated from the same registry used by the API dispatcher. The complete schemas, required headers and error responses are in the downloadable OpenAPI document.

POST/api/v1/humanize

Rewrite a document for clarity and natural flow

POST/api/v1/paraphrase

Paraphrase a document using the same preservation rules

GET/api/v1/usage

Read current UTC-month API usage

GET/api/v1/account

Read account credit balance and API entitlement

GET/api/v1/models

Read public processing capabilities and document limits

POST/api/v1/jobs

Queue a document for asynchronous processing

GET/api/v1/jobs/{id}

Read an owned job and its complete result

Build against the contract, then verify your account limits before sending production traffic.

View OpenAPI 3.1