Nesta página
Primeiros passos
Visão geral
A API tem a versão no caminho, /api/v1. Cada endpoint recebe um POST com corpo JSON e responde em JSON, inclusive nos erros.
URL base https://blurwrite.com
- POST /api/v1/detectAnalisar um texto
- POST /api/v1/detect/batchAnalisar vários textos
- POST /api/v1/humanizeHumanizar um texto
- POST /api/v1/paraphraseParafrasear um texto
- POST /api/v1/summarizeResumir um texto
- POST /api/v1/grammarVerificar gramática
Só no site, não na API: o contador de palavras, o contador de caracteres, o verificador de plágio e a opção "Usar mais tempo" do humanizador.
Gerada a partir do documento OpenAPI, esta seção lista exatamente as rotas e os campos que a API aceita. O documento OpenAPI
Sua primeira chamada
Um texto precisa ter pelo menos 50 palavras.
Verifique "calibrated" antes de tudo: quando for false, o idioma ainda não tem uma curva ajustada, então a pontuação não deve ser usada como resultado.
Cada valor é mostrado como seu tipo. Uma resposta real contém a análise do seu texto.
curl -X POST https://blurwrite.com/api/v1/detect \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/detect', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/detect",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null",
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}Autenticação
Envie sua chave no cabeçalho Authorization como um token bearer. Uma chave na URL é recusada.
Uma chave tem escopos: detect, rewrite, summarize e grammar. Uma rota retorna 403 out_of_scope quando a chave não tem o escopo necessário.
Authorization: Bearer YOUR_API_KEYEndpoints
POST /api/v1/detect
Analisar um texto. A análise do detector para um texto: uma pontuação de 0 a 100, o intervalo ao redor dela, uma análise por frase e a indicação de calibração do idioma.
Escopo da chave: detect
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| text | string | sim | O texto a analisar ou reescrever. |
| language | string | não | O código do idioma, como "en" ou "de". Se omitido, ele é detectado a partir do texto. |
| contentType | string | não | O tipo de texto, como "essay" ou "email", quando a análise deve usar a curva desse tipo de texto. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| figure | number | A pontuação de 0 a 100: a probabilidade de o texto ter sido escrito por uma máquina. |
| low | number | O limite inferior do intervalo ao redor da pontuação. |
| high | number | O limite superior do intervalo ao redor da pontuação. |
| uncertainty | number | Metade da largura do intervalo, em pontos. |
| verdict | string | A faixa em que a pontuação se encontra; uma faixa, nunca uma conclusão sobre quem escreveu o texto. Um destes: human, uncertain, ai. |
| confidence | string | O quanto se pode confiar na análise. Um destes: low, medium, high. |
| sentences | array de SentenceScore | Uma análise por frase. |
| words | integer | As palavras analisadas. |
| language | string | O idioma usado para analisar o texto. |
| model | string | O modelo que produziu a análise. |
| calibrated | boolean | Se o idioma tem uma curva ajustada. Quando for false, a pontuação não deve ser usada como resultado. |
| bandHumanFlagRate | number | null | A frequência com que textos humanos nesta faixa foram classificados como escritos por máquina nas nossas medições, ou null. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | no_text | O corpo não contém "text". |
| 422 | too_short | O texto está abaixo do tamanho mínimo. |
| 413 | text_too_long | O texto é maior do que o mecanismo consegue analisar em uma chamada. Divida-o. Nada foi contabilizado. |
| 422 | not_calibrated | O idioma ainda não pode ser analisado. |
| 503 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 502 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 503 | engine_starting | O mecanismo está iniciando e não ficou pronto a tempo. Nada foi contabilizado. Tente novamente em um minuto. |
| 503 | engine_busy | O mecanismo estava ocupado e a análise não pôde começar a tempo; as análises de usuários Pro do site têm prioridade sobre as chamadas de API. Nada foi contabilizado. Tente novamente em instantes. |
| 504 | engine_timeout | O mecanismo não terminou de analisar o texto a tempo. Nada foi contabilizado. Tente novamente ou envie um texto mais curto. |
| 429 | concurrency_limited | Esta chave já atingiu o limite de chamadas deste tipo em execução. Aguarde uma delas terminar ou o tempo indicado em Retry-After. |
curl -X POST https://blurwrite.com/api/v1/detect \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/detect', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/detect",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null",
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}POST /api/v1/detect/batch
Analisar vários textos. Até o limite de textos por lote em uma chamada. A chamada precisa reservar antecipadamente as palavras de cada texto que pode analisar (50 palavras ou mais); as palavras de qualquer texto que não retornar uma análise são devolvidas depois. A falha de um texto nunca faz o lote inteiro falhar.
Escopo da chave: detect
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| items | array de object | sim | Os textos, cada um com seu próprio "text" e, opcionalmente, "id", "language" e "contentType". |
| items[].id | string | não | Seu próprio id para o item, retornado com o resultado. Se omitido, a posição do item é usada. |
| items[].text | string | sim | O texto a analisar ou reescrever. |
| items[].language | string | não | O código do idioma, como "en" ou "de". Se omitido, ele é detectado a partir do texto. |
| items[].contentType | string | não | O tipo de texto, como "essay" ou "email", quando a análise deve usar a curva desse tipo de texto. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| results | array de BatchResult | Um resultado por item, na ordem de envio. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | batch_empty | O corpo não contém "items" ou a lista está vazia. |
| 413 | batch_too_large | O lote tem mais itens do que o limite permitido. |
| 429 | concurrency_limited | Esta chave já atingiu o limite de chamadas deste tipo em execução. Aguarde uma delas terminar ou o tempo indicado em Retry-After. |
curl -X POST https://blurwrite.com/api/v1/detect/batch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"items":[{"id":"1","text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."},{"id":"2","text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}]}'const res = await fetch('https://blurwrite.com/api/v1/detect/batch', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"items": [
{
"id": "1",
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
},
{
"id": "2",
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}
]
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/detect/batch",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"items": [
{
"id": "1",
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
{
"id": "2",
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
],
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"results": [
{
"id": "string",
"detection": {
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null"
},
"error": {
"code": "string",
"message": "string"
}
}
],
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}POST /api/v1/humanize
Humanizar um texto. O humanizador com suas verificações de fatos: números, nomes e citações são preservados, e uma reescrita que alterou um fato é corrigida ou sinalizada. O modo "custom" (Pro) escreve no seu estilo, identificado a partir de uma amostra da sua escrita.
Pela API, o humanizador faz a reescrita padrão. "Usar mais tempo" está disponível só no site.
Escopo da chave: rewrite
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| text | string | sim | O texto a analisar ou reescrever. |
| mode | string | não | O modo de reescrita. Um destes: natural, formal, simple, academic, creative, shorten, expand, custom. Padrão: natural. |
| style_sample | string | não | Com o modo "custom": uma amostra da sua escrita, de 150 a 2.000 palavras, analisada no servidor. Se omitida, a amostra salva na sua conta é usada. |
| tab | string | não | A aba do humanizador: o registro linguístico usado na reescrita. Padrão mantém o registro do texto original. Um destes: standard, academic, professional, casual. Padrão: standard. |
| strength | string | não | Regular mantém o conteúdo e o registro linguístico. Agressiva pode reorganizar o texto e omitir detalhes, mas mantém todos os pontos principais. Algumas partes podem soar pouco naturais. Um destes: regular, aggressive. Padrão: regular. |
| ownTouch | string | não | Um detalhe, exemplo ou opinião com suas próprias palavras, de até 400 caracteres, incorporado à reescrita. |
| language | string | não | O código do idioma, como "en" ou "de". Se omitido, ele é detectado a partir do texto. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| text | string | O texto reescrito. |
| before | Detection | A análise do detector para seu texto, ou null quando não houver. |
| after | Detection | A análise do detector para a reescrita, ou null. |
| passes | integer | Quantas reescritas foram produzidas antes de esta ser escolhida. |
| facts | object | O que as verificações de fatos encontraram e por que uma reescrita tem problemas, quando for o caso. |
| late | boolean | True quando a reescrita foi retornada ao atingir o limite de tempo, com as verificações incompletas. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | no_text | O corpo não contém "text". |
| 422 | too_short | O texto está abaixo do tamanho mínimo. |
| 400 | unknown_mode | O modo não está entre os oferecidos por esta rota. |
| 400 | unknown_option | A aba ou a intensidade não está disponível nesta rota. |
| 402 | plan_required | O modo, a aba, a intensidade ou o toque pessoal exige um plano que a conta não tem; o modo "custom" exige Pro. Nada foi contabilizado. |
| 400 | no_sample | O modo "custom" precisa de uma amostra de escrita, enviada ou salva na conta. |
| 400 | sample_too_short | A amostra de escrita está abaixo do tamanho mínimo. |
| 400 | sample_too_long | A amostra de escrita está acima do tamanho máximo. |
| 429 | concurrency_limited | Esta chave já atingiu o limite de chamadas deste tipo em execução. Aguarde uma delas terminar ou o tempo indicado em Retry-After. |
| 422 | no_rewrite | O mecanismo respondeu, mas nenhum rascunho passou nas verificações (vazio, recusa ou cópia do texto). Nada foi contabilizado. |
| 503 | timeout | A reescrita demorou demais e foi interrompida. Nada foi contabilizado. |
| 503 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 502 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
curl -X POST https://blurwrite.com/api/v1/humanize \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/humanize', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/humanize",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"text": "string",
"before": {
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null"
},
"after": {
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null"
},
"passes": "integer",
"facts": "object",
"late": "boolean",
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}POST /api/v1/paraphrase
Parafrasear um texto. O parafraseador, com a mesma lista de modos da ferramenta de paráfrase.
Escopo da chave: rewrite
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| text | string | sim | O texto a analisar ou reescrever. |
| mode | string | não | O modo de reescrita. Um destes: standard, fluency, formal, academic, simple, creative, expand, shorten. Padrão: standard. |
| strength | string | não | O quanto a reescrita pode se afastar do original. Um destes: readable, balanced, strong. Padrão: balanced. |
| readability | string | não | O registro de linguagem da escrita. Um destes: casual, professional, academic, creative. Padrão: professional. |
| purpose | string | não | A finalidade do texto. Um destes: general, essay, article, email, marketing, report, story. Padrão: general. |
| synonyms | string | não | Com que liberdade as palavras podem ser substituídas. Um destes: few, some, many. Padrão: some. |
| freezeWords | array de string | não | Palavras e expressões que devem ser retornadas exatamente como foram escritas: no máximo 25, cada uma com até 60 caracteres. Suas palavras entram na contagem de palavras da chamada. |
| customInstruction | string | não | Uma instrução curta sua para a reescrita, com até 500 caracteres. Suas palavras entram na contagem de palavras da chamada. |
| language | string | não | O código do idioma, como "en" ou "de". Se omitido, ele é detectado a partir do texto. |
| closedLoop | boolean | não | Defina como false para pular o ciclo fechado. Padrão: true. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| text | string | O texto reescrito. |
| before | Detection | A análise do detector para seu texto, ou null quando não houver. |
| after | Detection | A análise do detector para a reescrita, ou null. |
| passes | integer | Quantas reescritas foram produzidas antes de esta ser escolhida. |
| facts | object | O que as verificações de fatos encontraram e por que uma reescrita tem problemas, quando for o caso. |
| late | boolean | True quando a reescrita foi retornada ao atingir o limite de tempo, com as verificações incompletas. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | no_text | O corpo não contém "text". |
| 422 | too_short | O texto está abaixo do tamanho mínimo. |
| 400 | unknown_mode | O modo não está entre os oferecidos por esta rota. |
| 400 | option_invalid | freezeWords não é uma lista de palavras ou frases. Nada foi contabilizado. |
| 400 | option_too_long | freezeWords ou customInstruction excede o limite. Nada foi contabilizado. |
| 429 | concurrency_limited | Esta chave já atingiu o limite de chamadas deste tipo em execução. Aguarde uma delas terminar ou o tempo indicado em Retry-After. |
| 422 | no_rewrite | O mecanismo respondeu, mas nenhum rascunho passou nas verificações (vazio, recusa ou cópia do texto). Nada foi contabilizado. |
| 503 | timeout | A reescrita demorou demais e foi interrompida. Nada foi contabilizado. |
| 503 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 502 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
curl -X POST https://blurwrite.com/api/v1/paraphrase \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/paraphrase', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/paraphrase",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"text": "string",
"before": {
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null"
},
"after": {
"figure": "number, 0 a 100",
"low": "number, 0 a 100",
"high": "number, 0 a 100",
"uncertainty": "number",
"verdict": "human | uncertain | ai",
"confidence": "low | medium | high",
"sentences": [
{
"text": "string",
"score": "number, 0 a 1",
"verdict": "human | uncertain | ai"
}
],
"words": "integer",
"language": "string",
"model": "string",
"calibrated": "boolean",
"bandHumanFlagRate": "number | null"
},
"passes": "integer",
"facts": "object",
"late": "boolean",
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}POST /api/v1/summarize
Resumir um texto. O resumidor, em frases principais, um parágrafo ou tópicos.
Escopo da chave: summarize
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| text | string | sim | O texto a analisar ou reescrever. |
| mode | string | não | O formato do resumo. Um destes: key-sentences, paragraph, bullets. Padrão: key-sentences. |
| length | string | não | O tamanho do resumo. Um destes: short, medium, long. Padrão: medium. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| text | string | O resumo. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | no_text | O corpo não contém "text". |
| 422 | too_short | O texto está abaixo do tamanho mínimo. |
| 429 | concurrency_limited | Esta chave já atingiu o limite de chamadas deste tipo em execução. Aguarde uma delas terminar ou o tempo indicado em Retry-After. |
| 503 | timeout | A reescrita demorou demais e foi interrompida. Nada foi contabilizado. |
| 503 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 502 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
curl -X POST https://blurwrite.com/api/v1/summarize \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/summarize', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/summarize",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"text": "string",
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}POST /api/v1/grammar
Verificar gramática. Problemas de gramática, ortografia, pontuação e estilo, cada um com sua posição no texto e substituições sugeridas.
Escopo da chave: grammar
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| text | string | sim | O texto a analisar ou reescrever. |
| language | string | não | O código do idioma para a revisão, como "en-US" ou "de-DE". Padrão: en-US. |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
| issues | array de GrammarIssue | Os problemas encontrados, na ordem em que aparecem. |
| usage | Usage | O que esta chamada contabilizou. |
Erros específicos desta rota
| Status | Código | Significado |
|---|---|---|
| 400 | no_text | O corpo não contém "text". |
| 503 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 502 | engine_unavailable | O mecanismo não respondeu. Nada foi contabilizado. |
| 503 | engine_starting | O mecanismo está iniciando e não ficou pronto a tempo. Nada foi contabilizado. Tente novamente em um minuto. |
| 504 | engine_timeout | O mecanismo não terminou de analisar o texto a tempo. Nada foi contabilizado. Tente novamente ou envie um texto mais curto. |
curl -X POST https://blurwrite.com/api/v1/grammar \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."}'const res = await fetch('https://blurwrite.com/api/v1/grammar', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio."
}),
})
const data = await res.json()
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`)import os
import requests
res = requests.post(
"https://blurwrite.com/api/v1/grammar",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"text": "O comitê se reuniu na terça-feira para revisar o plano da nova biblioteca. Os membros concordaram que a sala de leitura deveria ficar aberta até mais tarde nos dias úteis e pediram à equipe que preparasse um orçamento para as horas extras. A próxima reunião analisará os custos, o provável número de visitantes e o impacto no restante do prédio.",
},
timeout=90,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}"){
"issues": [
{
"offset": "integer",
"length": "integer",
"message": "string",
"shortMessage": "string",
"category": "grammar | spelling | punctuation | style | typography",
"replacements": [
"string"
],
"context": "string"
}
],
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}Referência
Erros
Um erro responde com seu status HTTP e um corpo neste formato. Use o código para decidir; a mensagem diz o que deu errado e o que fazer em seguida.
Erros que qualquer rota pode retornar
| Status | Código | Significado |
|---|---|---|
| 401 | key_in_url | A chave foi enviada na URL. Envie-a no cabeçalho Authorization. |
| 401 | no_key | Nenhuma chave foi enviada. |
| 401 | bad_key | A chave não é válida ou foi revogada. |
| 403 | out_of_scope | A chave não tem o escopo necessário para esta rota. |
| 429 | rate_limited | Muitas requisições para esta chave. Aguarde o tempo indicado em Retry-After. |
| 403 | plan_lapsed | O plano da conta não inclui mais a API. |
| 413 | too_large | A requisição é grande demais. |
| 400 | bad_body | O corpo não é um objeto JSON. |
| 413 | too_many_words | A chamada tem mais palavras do que o permitido por chamada. Divida o texto. Nada foi contabilizado. |
| 402 | quota_exhausted | As palavras de API do plano para este período de cobrança acabaram e o saldo de recarga está vazio. Nada foi contabilizado. |
| 402 | quota_short | A chamada precisa de mais palavras do que a soma das palavras de API restantes do plano e do saldo. Nada foi contabilizado. |
| 402 | monthly_ceiling | A conta atingiu seu limite de API deste período de cobrança, que se aplica independentemente do saldo. Nada foi contabilizado. |
| 503 | store_unavailable | Não foi possível ler a chave, a contagem de palavras da conta ou a amostra de escrita salva neste momento, ou esta implantação não tem armazenamento de contas. Nada foi executado ou contabilizado. |
Uma chamada reserva as palavras antes de ser executada e as devolve se falhar. Se não for possível registrar a contagem de palavras naquele momento, elas continuam sendo contabilizadas: uma chamada com falha informa isso e inclui "recorded": false nos dados de uso, um lote retorna "recorded": false nos dados de uso, e a quantidade de palavras não é estimada.
{
"error": {
"code": "string",
"message": "string",
"docs": "string",
"available": "integer"
},
"usage": {
"recorded": "boolean",
"words": "integer",
"source": "plan | balance | plan_and_balance",
"fromPlan": "integer",
"fromBalance": "integer",
"allowanceLeft": "integer | null",
"balance": "integer"
}
}Limites
Todos os valores aqui correspondem aos limites aplicados pela API.
- Cada chave faz no máximo 60 requisições a cada 60 segundos.
- Cada chave pode ter no máximo 4 chamadas de detecção (um lote conta como uma) e 2 chamadas de humanização, reescrita ou resumo em execução ao mesmo tempo; uma chamada adicional recebe a resposta 429 concurrency_limited com um Retry-After.
- Quando os mecanismos estão ocupados, as análises das contas Pro do site são processadas antes das chamadas de API, então uma chamada de API pode precisar esperar sua vez.
- Um lote contém no máximo 50 textos.
- Cada chamada aceita no máximo 20.000 palavras, seja em um único texto ou em um lote inteiro.
- O detector analisa um texto de até 90.000 caracteres, cerca de 10.000 palavras, em qualquer plano. Um texto maior recebe a resposta 413 text_too_long, mesmo dentro do limite de palavras da chamada.
- Uma conta pode ter até 5 chaves ativas, permitindo substituir uma chave sem interrupção do serviço.
Objetos de resposta
Os objetos que os endpoints retornam, campo por campo.
Detection
| Campo | Tipo | Descrição |
|---|---|---|
| figure | number | A pontuação de 0 a 100: a probabilidade de o texto ter sido escrito por uma máquina. |
| low | number | O limite inferior do intervalo ao redor da pontuação. |
| high | number | O limite superior do intervalo ao redor da pontuação. |
| uncertainty | number | Metade da largura do intervalo, em pontos. |
| verdict | string | A faixa em que a pontuação se encontra; uma faixa, nunca uma conclusão sobre quem escreveu o texto. Um destes: human, uncertain, ai. |
| confidence | string | O quanto se pode confiar na análise. Um destes: low, medium, high. |
| sentences | array de SentenceScore | Uma análise por frase. |
| words | integer | As palavras analisadas. |
| language | string | O idioma usado para analisar o texto. |
| model | string | O modelo que produziu a análise. |
| calibrated | boolean | Se o idioma tem uma curva ajustada. Quando for false, a pontuação não deve ser usada como resultado. |
| bandHumanFlagRate | number | null | A frequência com que textos humanos nesta faixa foram classificados como escritos por máquina nas nossas medições, ou null. |
SentenceScore
| Campo | Tipo | Descrição |
|---|---|---|
| text | string | A frase. |
| score | number | De 0 a 1, a probabilidade de a frase ter sido escrita por uma máquina. |
| verdict | string | A faixa em que a frase se encontra. Um destes: human, uncertain, ai. |
Usage
| Campo | Tipo | Descrição |
|---|---|---|
| recorded | boolean | True quando a contagem foi registrada. False apenas quando um lote não conseguiu devolver suas palavras não analisadas; nesse caso, apenas "words" está presente. |
| words | integer | As palavras contabilizadas nesta chamada. |
| source | string | De onde vieram: as palavras de API do plano, o saldo de recarga ou ambos. Um destes: plan, balance, plan_and_balance. |
| fromPlan | integer | As palavras descontadas das palavras de API do plano. Presente quando recorded é true. |
| fromBalance | integer | As palavras descontadas do saldo de recarga. Presente quando recorded é true. |
| allowanceLeft | integer | null | As palavras restantes do plano para esta ferramenta após esta chamada, no período de cobrança atual. Null para uma ferramenta sem cota neste plano. Presente quando recorded é true. |
| balance | integer | O saldo de recarga restante após esta chamada. Presente quando recorded é true. |
RewriteResult
| Campo | Tipo | Descrição |
|---|---|---|
| text | string | O texto reescrito. |
| before | Detection | A análise do detector para seu texto, ou null quando não houver. |
| after | Detection | A análise do detector para a reescrita, ou null. |
| passes | integer | Quantas reescritas foram produzidas antes de esta ser escolhida. |
| facts | object | O que as verificações de fatos encontraram e por que uma reescrita tem problemas, quando for o caso. |
| late | boolean | True quando a reescrita foi retornada ao atingir o limite de tempo, com as verificações incompletas. |
GrammarIssue
| Campo | Tipo | Descrição |
|---|---|---|
| offset | integer | Onde o problema começa no texto enviado, em unidades de código UTF-16 (um índice de string JavaScript). |
| length | integer | Quantas unidades de código UTF-16 do texto enviado o problema abrange. |
| message | string | O que está errado. |
| shortMessage | string | O mesmo, em poucas palavras. |
| category | string | O tipo de problema. Um destes: grammar, spelling, punctuation, style, typography. |
| replacements | array de string | Substituições sugeridas, com as melhores primeiro. |
| context | string | O texto ao redor do problema. |
BatchResult
| Campo | Tipo | Descrição |
|---|---|---|
| id | string | O id do item. |
| detection | Detection | A análise, quando o item retornou uma. |
| error | object | Por que o item não retornou uma análise. |
Error
| Campo | Tipo | Descrição |
|---|---|---|
| error | object | |
| usage | Usage | O que esta chamada contabilizou. |
O servidor MCP
Um agente pode acessar as mesmas ferramentas pelo Model Context Protocol. O servidor é apenas um cliente desta API, então o agente recebe exatamente a mesma análise que o site fornece.
- detect_textAnalisa um texto.
- detect_batchAnalisa vários textos.
- humanize_textHumaniza um texto com verificação de fatos.
- paraphrase_textReescreve um texto.
- summarize_textResume um texto.
- check_grammarVerifica a gramática e a ortografia.
Claude Code Conecta online
Guarde sua chave de API em uma variável de ambiente chamada BLURWRITE_API_KEY, onde o cliente é executado:
Execute isto em um terminal:
Ou coloque isto no .mcp.json:
.mcp.json{ "mcpServers": { "blurwrite": { "type": "http", "url": "https://blurwrite.com/api/mcp", "headers": { "Authorization": "Bearer ${BLURWRITE_API_KEY}" } } } }Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Claude Desktop Usa o arquivo do servidor
Baixe o arquivo do servidor e anote onde você o salvou. Ele precisa do Node.js.
Baixar o arquivo do servidorNo aplicativo: Settings > Developer > Edit Config.
Adicione isto ao claude_desktop_config.json:
claude_desktop_config.json{ "mcpServers": { "blurwrite": { "command": "node", "args": [ "/path/to/server.mjs" ], "env": { "BLURWRITE_API_KEY": "YOUR_API_KEY" } } } }Feche e abra o Claude Desktop de novo para que ele carregue o servidor.
Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Claude (claude.ai) Em breve
Em breve será possível conectar o claude.ai fazendo login na sua conta Blurwrite. Até lá, as mesmas ferramentas já funcionam no Claude Desktop com o arquivo do servidor, ou no Claude Code, com a configuração nas abas de cada um.
Somente se sua organização tiver a opção de cabeçalhos de requisição para conectores personalizados: adicione o endereço com este cabeçalho.
ChatGPT Em breve
Em breve será possível conectar o ChatGPT fazendo login na sua conta Blurwrite. Até lá, as mesmas ferramentas já funcionam no Codex e no Claude Code, com a configuração nas abas de cada um.
Codex Conecta online
Guarde sua chave de API em uma variável de ambiente chamada BLURWRITE_API_KEY, onde o cliente é executado:
Execute isto em um terminal:
Ou coloque isto no ~/.codex/config.toml:
~/.codex/config.toml[mcp_servers.blurwrite] url = "https://blurwrite.com/api/mcp" bearer_token_env_var = "BLURWRITE_API_KEY"No aplicativo: MCP servers > Add server > Streamable HTTP.
Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Cursor Conecta online
Guarde sua chave de API em uma variável de ambiente chamada BLURWRITE_API_KEY, onde o cliente é executado:
Adicione isto ao ~/.cursor/mcp.json:
~/.cursor/mcp.json{ "mcpServers": { "blurwrite": { "url": "https://blurwrite.com/api/mcp", "headers": { "Authorization": "Bearer ${env:BLURWRITE_API_KEY}" } } } }Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
VS Code (Copilot) Conecta online
Adicione isto ao .vscode/mcp.json:
.vscode/mcp.json{ "inputs": [ { "type": "promptString", "id": "blurwrite-key", "description": "Blurwrite API key", "password": true } ], "servers": { "blurwrite": { "type": "http", "url": "https://blurwrite.com/api/mcp", "headers": { "Authorization": "Bearer ${input:blurwrite-key}" } } } }Quando o servidor inicia, o VS Code pede sua chave uma vez e a guarda.
Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Windsurf Conecta online
Guarde sua chave de API em uma variável de ambiente chamada BLURWRITE_API_KEY, onde o cliente é executado:
No aplicativo: Cascade > ... > Open MCP config file.
Adicione isto ao mcp_config.json:
mcp_config.json{ "mcpServers": { "blurwrite": { "serverUrl": "https://blurwrite.com/api/mcp", "headers": { "Authorization": "Bearer ${env:BLURWRITE_API_KEY}" } } } }Feche e abra o Windsurf de novo para que ele carregue o servidor.
Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Gemini CLI Conecta online
Guarde sua chave de API em uma variável de ambiente chamada BLURWRITE_API_KEY, onde o cliente é executado:
Execute isto em um terminal:
Ou coloque isto no ~/.gemini/settings.json:
~/.gemini/settings.json{ "mcpServers": { "blurwrite": { "httpUrl": "https://blurwrite.com/api/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } }Verifique se funciona: peça ao seu assistente "Analise este parágrafo com o Blurwrite e me diga o intervalo e o nível de confiança."
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Other clients Online, uma ponte ou o arquivo
Um cliente que se conecta a servidores MCP remotos por HTTP precisa apenas destes dois valores:
Um cliente que só inicia servidores locais pode acessar o endereço pela ponte de código aberto mcp-remote (ela precisa do Node.js):
Ou execute você mesmo nosso arquivo de servidor:
Baixar o arquivo do servidor
Sua chave de API fica no seu painel, em API. Nunca coloque uma chave em um arquivo compartilhado ou em um repositório.
Toda análise recebida por um agente inclui o valor, a incerteza associada e o estado de calibração, para que o agente possa explicar o que a análise significa e quando ela não deve ser usada.
Sua chave
Entre na sua conta e crie uma chave no seu painel.
As chaves nunca são criadas nesta página.
O que a API e o servidor MCP fazem