AI Content Detector API: 1 of 233 Human Posts
An AI content detector API that flags 1 of 233 human posts and catches 77% of AI posts. Filter a feed or score one text. 91% of AI posts of 40+ words caught.
An AI content detector API flagged 1 of 233 human posts at the default likely cut, on a 467-post bench. The same bench caught 77% of the AI posts, and 91% of AI posts of 40 words or more.
Add label=ai_written on a post list that accepts label=, or send one passage to GET /v1/utility/ai-detection. Both calls share one judgment and return the same p, level, and model. The list can drop rows, and the utility call does not.
The bodies below are the capture from 2026-10-23. The query was remote work, with sort=latest, 20 posts, from GET /v1/twitter/search/tweets. That page had 0 likely rows. It is the page that came back, not a rate of AI writing, and not the 1 of 233 bench figure.
What does an AI text detection API return?
On a post list, an AI text detection API returns computed.labels.ai_written, with p from 0 to 1 or null, plus level and model. When you already hold the text, GET /v1/utility/ai-detection?text= returns those three and also kind (ai_detection), version, words, and characters. The model name today is sc-ai-written-1. A new name means a new scale, so store that name next to any p.
The bands are the published cuts. They were not fitted on the page below. likely means p at or above 0.95. possible means p at or above 0.71. too_short means under 8 words, with p null. No numeric floor for unlikely is published. The docs do not say that possible stops below 0.95, and they do not say that unlikely is everything under 0.71.
The same text gets the same judgment on the list row and on the utility call. Only the list can drop rows. The parameter is for post lists that accept label=. Comment lists and review lists are outside that scope. The classifier is SocialCrawl's own text classifier, trained for this question, rather than a prompt sent to a general-purpose model. Field names are on the AI-written detection page.
How do you detect AI-written posts in a feed?
You detect AI-written posts by adding label=ai_written to a search you already needed. On 2026-10-23 that search was latest tweets for remote work.
curl "https://www.socialcrawl.dev/v1/twitter/search/tweets?query=remote%20work&sort=latest&label=ai_written" \
-H "x-api-key: $SOCIALCRAWL_API_KEY"The call returned 20 posts. Request req-Vrhq0Ujb1ICrcG47 used 2 credits, and data.labels.extra_credits was 1. The label block reported rows 20, labelled 20, and cached 0. Every row's model was sc-ai-written-1. p was null only on the two too_short rows.
The JSON keeps the label on post 2113759655029834135 and data.labels. The other 19 items are left out. credits_used and request_id are the values recorded for this response.
{
"credits_used": 2,
"request_id": "req-Vrhq0Ujb1ICrcG47",
"data": {
"items": [
{
"computed": {
"labels": {
"ai_written": {
"p": 0.904,
"level": "possible",
"model": "sc-ai-written-1"
}
}
}
}
],
"labels": {
"presets": ["ai_written"],
"rows": 20,
"labelled": 20,
"cached": 0,
"dropped": 0,
"dropped_ids": [],
"extra_credits": 1
}
}
}That post is 345 words on a whitespace split of the full text, with list p 0.904 and level possible. Among the 10 rows with at least 40 whitespace-separated words, it had the highest p, so it was the text sent to the utility call. The 240-character trim of the row is below.
Fieldwatch 1.1.31 is out with two big additions. Fieldwatch is a free, open-source Android app that identifies the devices around you, including what might be watching or following you: trackers, cameras, drones (it even decodes their Remot…
| Level | Rows |
|---|---|
| likely | 0 |
| possible | 1 |
| unlikely | 17 |
| too_short | 2 |
The four counts sum to 20. One possible row out of 20 is not a rate of AI writing.
This page is not a set of remote-work essays. The possible post is a Fieldwatch note that hits on "Remote" (Remote ID) and "works". The longest unlikely post is 291 words at p 0.619, id 2113764276959658076, and it is about a TV remote. Several other rows are near-duplicate job ads. Relevance on that search used mode score. It scored 20 rows, dropped 0, and added extra_credits 0 on that meter, so the keyword did not narrow the page.
A second search kept the query and sent label=ai_written with exclude=ai_written. Request req-XogFotrRhODYr5Rk returned the same 20 ids, in the same order, with the same p, level, and model. dropped was 0 and dropped_ids was empty. extra_credits was 0 because the 20 judgments were cached (cached 20), and credits_used was 1 for the search only. The response cached flag was false. The possible row stayed. Both too_short rows stayed.
exclude removed zero rows, because none were likely. The default drop removes likely only. This page had no likely row, so nothing was removed.
How do you check if one text is AI-generated?
The utility call scored the exact post.content.text of post 2113759655029834135, 1956 characters, not the trim above. The full text is not reprinted here.
curl -G "https://www.socialcrawl.dev/v1/utility/ai-detection" \
--data-urlencode "text=PASTE_THE_EXACT_POST_TEXT" \
-H "x-api-key: $SOCIALCRAWL_API_KEY"PASTE_THE_EXACT_POST_TEXT stands in for that 1956-character string. The response keeps kind, version, model, p, level, words, characters, credits_used, and request_id.
{
"data": {
"kind": "ai_detection",
"version": 1,
"model": "sc-ai-written-1",
"p": 0.904,
"level": "possible",
"words": 345,
"characters": 1956
},
"credits_used": 1,
"request_id": "req-bM4d42vsVRyKZYmQ",
"cached": false
}Request req-bM4d42vsVRyKZYmQ cost 1 credit. cached was false on this call. List row and utility body match on this text. Both p values are 0.904, both levels are possible, and both name sc-ai-written-1. The utility words field is 345, the same whitespace count as the list text. The match is only for the text that was sent.
The post is 1956 characters, and the classifier reads about the first 1,000. A matching p does not mean the tail was scored on its own. The 1,000-character read is the labels-page rule. The utility page does not document that cut. The single-text route is score one text.
A second call sent the exact string Short post. It returned kind ai_detection, version 1, model sc-ai-written-1, p null, level too_short, words 2, and characters 10. Request req-ffY7XACAKBhJQHvM cost 1 credit, and cached was false. Under 8 words the model does not guess. The Short post call does not re-measure the short-post line on the bench.
What did the 467-post bench flag at likely?
These calls did not re-measure the bench. The figures here are the published bench, in how the labels are measured.
The set is 467 posts the model had not seen. 233 were written by people, from X and Reddit through November 2022, before ChatGPT existed. 234 were written by 8 current models: GPT-5.5, GPT-5.4 mini, GPT-4o mini, gpt-oss, Claude Sonnet 4.5, Claude Haiku 4.5, Gemini 3 Flash, and Grok 4.3. A third of the AI posts were prompted to sound like a person.
At likely, the default drop, 1 of 233 human posts was flagged. The bench caught 77% of AI posts, and 91% of AI posts of 40 words or more. At possible and above, 12 of 233 human posts were flagged, 95% of AI posts were caught, and 99% of AI posts of 40 words or more were caught.
Under about 40 words, likely catches about 2 in 5 AI posts. Gemini 3 Flash was the hardest of the 8 models, at 28% for likely and 79% at possible or above. The 77% and 95% figures are overall rates. One model can sit far from them, as Gemini 3 Flash does. No other per-model rate is published.
This AI content detection API was measured on English. Other languages, including Korean, return a score and are unmeasured. No Korean figure exists.
The score is a probability you can filter or sort on. A person can be flagged, and an AI-written post can pass. A high p does not identify the author. Edited text can land anywhere on the scale, whether a person rewrote a draft or a model polished a person's post.
How does ai_style differ from ai_written?
label=ai_style counts checkable writing patterns and reports a pattern_count. The default drop is pattern_count at or above 2. It does not answer authorship, so a person who writes in those patterns is flagged too. ai_written is the probability.
Under about eight words, ai_written is too_short, p is null, and the row is never dropped. ai_style still fills counts, and pattern_count can still reach 2. See the writing-pattern label. This page did not request ai_style.
How do you filter AI-generated social posts?
You filter AI-generated social posts with exclude=ai_written on the same request as label=ai_written. That drops likely only. To also drop possible, set ai_written_threshold=0.71 on that same request. This page did not set it, which is why p 0.904 stayed.
The utility call costs 1 credit and stores nothing. Text is capped at 8,000 characters and must be URL-encoded. A call that cannot be scored is HTTP 503 and is not charged. Those are documented rules. This harvest did not capture a 503, and it did not observe storage. ai-detection is the exception. The utility intro that prices every utility call at zero does not cover this one.
The endpoint will accept 8,000 characters. The classifier reads about the first 1,000, which the labels page describes as nearly always the whole social post. The utility page documents the 8,000-character cap. It does not document the 1,000-character read.
On a list, posts newly judged on that request cost 1 credit per started 25. A 20-post page adds 1. The first search did that, with extra_credits 1 inside credits_used 2. Rows already scored add nothing, and a cached page of judgments adds nothing. The exclude search is the cached case. extra_credits was 0, data.labels.cached was 20, and credits_used was 1. The field is data.labels.extra_credits. dry_run=1 shows the ceiling first, on the same meter as the other opt-in post labels.
The four data calls cost 2 credits, then 1, then 1, then 1. That is the labelled search, the Fieldwatch utility call, Short post, and the exclude search.
Unscored rows and too_short rows are never dropped. Fail-open is the name used here for that rule. The docs page does not use the word. Both short rows stayed. It had no unscored row. The docs do not state the status code for exclude without label.
How do you start using this?
Create a key from create an API key, then open https://www.socialcrawl.dev/dashboard/api/keys. Both calls take one API key in x-api-key. The curls above send $SOCIALCRAWL_API_KEY to the SocialCrawl API.
The list URL is GET https://www.socialcrawl.dev/v1/twitter/search/tweets?query=remote%20work&sort=latest&label=ai_written. Put exclude=ai_written on that same URL if you want the default drop. For one passage, URL-encode the text and call GET https://www.socialcrawl.dev/v1/utility/ai-detection?text=. A string under 8 words, such as Short post, comes back too_short with p null.
sort=latest means a later run will not return these same 20 posts. The bands live on AI-written detection, and the single-text call is score one text. When possible should leave the feed too, add ai_written_threshold=0.71 beside label=ai_written and exclude=ai_written.
Frequently asked questions
How much does an AI content detector API call cost?
The utility call costs 1 credit. On a post list, rows newly judged on that request cost 1 credit per started 25 posts, so a 20-post page adds 1 credit on top of the search. Request req-Vrhq0Ujb1ICrcG47 returned credits_used 2 and data.labels.extra_credits 1. A call that cannot be scored is HTTP 503 and is not charged. Other prices are on endpoint pricing and the pricing page.
What does a post under 8 words return?
The exact string Short post returned p null, level too_short, words 2, and characters 10, on model sc-ai-written-1. Request req-ffY7XACAKBhJQHvM cost 1 credit. A too_short row is never dropped. That call is only the under-8-word path. On the bench, under about 40 words, likely catches about 2 in 5 AI posts, which this two-word string did not measure.
Does the score cover languages other than English?
English is what the 467-post bench measured. A text in another language, including Korean, still receives a score from sc-ai-written-1. Those scores are unmeasured. No Korean accuracy number was published, so a Korean likely is not the 1-of-233 human figure and not the 77% figure for AI posts.
Is a high score proof a model wrote the post?
The score is a probability, not proof. On the published bench, likely flagged 1 of 233 human posts, and possible and above flagged 12 of 233. The live row at p 0.904 was possible and stayed in the feed, because the default drop is likely only and this page did not set ai_written_threshold=0.71. Edited text can land anywhere on the scale, whether a person rewrote a draft or a model polished a person's post. Do not read the Fieldwatch row as an accusation against its author.
Related posts
Sprout Social Alternative: Suite or Data API
The Sprout API is on the $399 Advanced annual plan per seat. Listening has no public price. A Sprout Social alternative is a suite. Export is a separate buy.
Audience Questions on Social Media: 120 Already Asked
We listed 120 audience questions on social media. 109 of those rows are comments. Sorted into who, what, why, how, and vs. Comment language is not a country.
Best TikTok Analytics Tools: 5 of 16 Absent
5 of 16 metrics were absent on 17 October 2026. 18 accounts, 180 posts, the smallest at 2,077,115 followers. A separate play count was absent on every post.
