API voor ontwikkelaars v2.1

Bouw op Nonli met een heldere API-naslag die klaar is voor AI.

Gebruik API-tokens, doorzoek berichten en listening-gegevens, maak korte links, publiceer berichten en upload video’s vanuit één gedocumenteerde API.

Basis-URL

https://api.nonli.com/v2.1
71endpoints
11resources

Snelstart

Drie gewoonten volstaan om te authenticeren, payloads klein te houden en productiegegevens voorspelbaar op te vragen.

bash
1curl --location 'https://api.nonli.com/v2.1/brands?size=1&fields=id,name' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
1

Een API-token aanmaken

Beheerders van het bedrijf maken en vernieuwen API-tokens in de back office van Nonli.

2

De Bearer-header meesturen

Stuur het token bij elk geauthenticeerd verzoek mee met Authorization: Bearer YOUR_API_TOKEN. Om een token te valideren roept u het hier getoonde brands-endpoint aan.

3

Exacte velden opvragen

Gebruik fields, filters, filtersOr, excludes, size, page en sort om antwoorden klein te houden, zowel voor apps als voor AI-agents.

Notities voor AI-integratie

OpenAPI JSON: /api-docs/openapi.json

llms.txt: /llms.txt

  • Gebruik bij voorkeur /api-docs/openapi.json om tools te genereren en schema’s te extraheren.
  • Gebruik /llms.txt als compact, crawlbaar startpunt.
  • API-tokens zijn toegangsgegevens met een bedrijfsrol, geen websessies van gebruikers: gebruik /me niet met Bearer-tokens.
  • Gebruik waar mogelijk de parameter fields om het tokenverbruik te beperken.
  • Houd rekening met de limieten per endpoint en doorloop grote datasets pagina voor pagina.

Endpoint-verkenner

71 endpoints

GETSearch brands/brandsOpenenGETGet a brand/brands/:brandIdOpenenGETSearch social accounts/social-accountsOpenenGETGet a social account/social-accounts/:socialAccountIdOpenenGETGet publishing quota/social-accounts/publishing-quotaOpenenGETGet YouTube playlists/social-accounts/youtube/playlistsOpenenPOSTCreate a YouTube playlist/social-accounts/youtube/playlistsOpenenPUTUpdate a YouTube playlist/social-accounts/youtube/playlists/:playlistIdOpenenDELETEDelete a YouTube playlist/social-accounts/youtube/playlists/:playlistIdOpenenGETList the videos of a YouTube playlist/social-accounts/youtube/playlists/:playlistId/itemsOpenenPUTMove a video in a YouTube playlist/social-accounts/youtube/playlists/:playlistId/items/:itemIdOpenenGETGet Pinterest boards/social-accounts/pinterest/boardsOpenenGETSearch posts/postsOpenenGETGet a post/posts/:postIdOpenenGETGet post categories/posts/categoriesOpenenGETGet post brands/posts/brandsOpenenGETGet post users/posts/usersOpenenGETGet post languages/posts/languagesOpenenGETGet post histogram/posts/histogramOpenenGETGet post aggregation/posts/aggregationOpenenGETGet post stats/posts/statsOpenenPOSTCheck post content/posts/checkOpenenGETGet post tags/posts/tagsOpenenGETGet post topics/posts/topicsOpenenPOSTCreate posts in bulk/posts/bulkOpenenPUTUpdate posts in bulk/posts/bulkOpenenDELETEDelete posts in bulk/posts/bulkOpenenGETSearch shortlinks/shortlinksOpenenGETGet a shortlink/shortlinks/:shortlinkIdOpenenGETGet shortlink stats/shortlinks/statsOpenenGETGet shortlink authors/shortlinks/authorsOpenenGETGet shortlink brands/shortlinks/brandsOpenenPOSTCreate a shortlink/shortlinksOpenenPOSTCreate shortlinks in bulk/shortlinks/bulkOpenenPUTUpdate a shortlink/shortlinks/:shortlinkIdOpenenPOSTGenerate a message for a shortlink/shortlinks/:shortlinkId/generate-messageOpenenGETSearch themes/themesOpenenGETGet a theme/themes/:themeIdOpenenPOSTCreate a theme/themesOpenenPUTUpdate a theme/themes/:themeIdOpenenDELETEDelete a theme/themes/:themeIdOpenenGETGet theme roles/themes/rolesOpenenGETGet social listening/listening/socialOpenenGETGet organic listening/listening/organicOpenenPUTUpsert an organic with videos/listening/organicOpenenGETGet organic content/listening/organic/:organicIdOpenenGETGet organic stats/listening/organic/statsOpenenGETGet organic aggregation/listening/organic/aggregationOpenenGETSuggest organic filter values/listening/organic/suggest/:fieldOpenenGETGet the leaderboard/posts/leaderboardOpenenPOSTSearch the leaderboard/posts/leaderboard/_searchOpenenGETGet leaderboard categories/posts/leaderboard/categoriesOpenenGETSearch accounts/accountsOpenenPOSTAdd an account/accountsOpenenGETGet account categories/accounts/categoriesOpenenGETSearch account locations/accounts/locationsOpenenGETGet account stats/accounts/statsOpenenGETSearch bots/botsOpenenGETGet a bot/bots/:botIdOpenenPOSTCreate bots in bulk/bots/bulkOpenenPUTUpdate bots in bulk/bots/bulkOpenenDELETEDelete a bot/bots/:botIdOpenenGETGet bot configuration info/bots/infoOpenenGETSearch media/mediaOpenenGETGet media tags/media/tagsOpenenPOSTUpload an image/upload/imageOpenenPOSTCreate upload video token/upload/video/tokenOpenenPOSTCheck uploaded video existence (legacy)/upload/video/existsOpenenPOSTUpload video chunk/upload/video/chunkOpenenPOSTCreate upload document token/upload/document/tokenOpenenPOSTUpload document chunk/upload/document/chunkOpenen

Veelgebruikte integratiestromen

5 endpoints
Op deze pagina

1.Conventies

Gedeelde regels die voor elk endpoint gelden.

Authenticatie

Stuur bij elke geauthenticeerde aanroep een API-token mee in de Authorization-header: Authorization: Bearer YOUR_API_TOKEN. API-tokens vertegenwoordigen een bedrijfsrol, geen websessie van een gebruiker, dus /me is niet beschikbaar met Bearer-tokens. Bewaar tokens veilig, vernieuw ze in de back office en zet ze nooit in querystrings.

Paginering

Lijst-endpoints geven total en een rows-array terug. Doorloop de resultaten met size en een op nul beginnende page totdat u total items hebt verzameld. Gebruik fields om elk item klein te houden. Bij GET /posts accepteert size 0 tot 100 en mag (page + 1) × size niet hoger zijn dan 10.000: diepere pagina’s geven 400 Bad Request terug, dus versmal de filters, bijvoorbeeld met een publishedAt-bereik, om oudere berichten te bereiken.

Datums en tijdzones

Tijdstempels zijn UTC in ISO-8601, bijvoorbeeld 2026-05-27T23:59:59Z. Datumparameters en datums in requestbodies, zoals createdAt, publishedAt of schedule.startDate, accepteren YYYY-MM-DDTHH:MM:SSZ met of zonder fracties van seconden, bijvoorbeeld 2026-05-27T23:59:59.123Z: een datum uit een antwoord kunt u ongewijzigd terugsturen. De fractie wordt genegeerd en een UTC-offset zoals +02:00 geeft 400 Bad Request terug. Datumbereikfilters gebruiken “..” tussen twee waarden, bijvoorbeeld publishedAt:-30 days..now; bij zoek-endpoints voor berichten en listening is de bovengrens uitgesloten.

Limieten

Limieten worden geteld per bedrijf en per endpoint, gedeeld door alle API-tokens van het bedrijf, in vaste vensters die beginnen bij de eerste aanroep. De endpoint-naslag toont elke limiet; een endpoint zonder limiet heeft geen limiet per endpoint. Elk antwoord van een endpoint met limiet bevat de headers RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset; RateLimit-Reset is het aantal seconden tot het venster opnieuw begint. Zodra de limiet is bereikt, geeft elke aanroep 429 terug tot het venster sluit, met een Retry-After-header met hetzelfde aantal seconden en een JSON-body. GET /listening/social met een Bearer-API-token telt mee voor het Social Listening-pakket van het bedrijf, zonder venster per endpoint en zonder RateLimit-headers; een legacy-sessie van een API-gebruiker is beperkt tot 720 aanroepen per 12 uur per gebruiker en ontvangt de RateLimit-headers. Een legacy-sessie van een API-gebruiker is een gebruiker die is ingelogd met de API-rol, geen Bearer-token.

Berichtstatussen

Zonder status-waarde in filters (filtersOr telt niet mee) geven GET /posts, /posts/aggregation en /posts/histogram alle berichten terug of tellen ze alle berichten, behalve verwijderde (404) en verouderde (410), dus ook concepten, geplande berichten, berichten die op controle wachten en mislukte publicaties. GET /posts/stats past geen standaardstatusfilter toe. Voeg filtersOr=status:200,203,204 toe, de groep “Gepubliceerd” van de back office, voor cijfers die overeenkomen met gepubliceerde content. De naslag van GET /posts vermeldt elke statuswaarde.

ID’s

Berichten, korte links en organische items gebruiken UUID’s als string. Merken, socialemedia-accounts en thema’s gebruiken gehele ID’s. Geef ID’s exact door zoals de API ze teruggeeft.

Tellernamen

Gebruik voor endpoints op basis van berichten de gedocumenteerde tellernamen in sort, filters, filtersOr, excludes, tellers van bot-triggers en meetwaarden voor de berichtsnelheid van bots. Endpoints voor Organic Listening en korte links hebben hun eigen tellers en wijzen berichttellers af met 400 Bad Request.

2.Zoekparameters

De meeste lijst-endpoints delen dezelfde querygrammatica.

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
pageintZero-based page number.Standaard: 0
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
sortstringSort expression. Prefix a field with "-" for descending order. Counter-backed endpoints can sort by counters.total.<field> or by the counter shorthand itself, for example sort=-engagement on post/social data or sort=-click on organic data.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
fieldsstringComma-separated fields to include in each returned item.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

3.Beschikbare tellers

Gebruik deze lijst als overzicht van de openbare tellers per endpointfamilie. Historische tellernamen die zijn vervangen, zijn bewust weggelaten.

Posts, Social Listening, and Bots

/posts/posts/categories/posts/brands/posts/users/posts/languages/posts/histogram/posts/aggregation/posts/stats/posts/tags/posts/topics/posts/leaderboard/posts/leaderboard/_search/posts/leaderboard/categories/listening/social/bots/bulk

Tellers

clickclick_uniquectrengagementfacebook_engagement_per_minuteweighted_facebook_engagementweighted_facebook_engagement_per_minutefacebook_commentfacebook_total_reactionfacebook_sharereachimpressionvideoViewsvideo_views_3secfacebook_post_video_avg_time_watchedvideo_completion_rateoverperformingrepostsquotesmonetizationsnapchat_screenshotssubscriberfacebook_link_clicksfacebook_other_clicksfacebook_photo_viewfacebook_video_playfacebook_post_video_views_60s_excludes_shorterinstagram_savedinstagram_total_interactionsinstagram_clips_replays_countlinkedin_private_click_countyoutube_likesyoutube_dislikesyoutube_estimated_minutes_watched

Opmerking: Use these names in post-backed counter filters, counter sorts, bot trigger counters, and bot post-rate metrics. Facebook reach is requested as reach; the API maps the current Meta reach metric internally. TikTok metrics currently feed the common post counters engagement, facebook_total_reaction, facebook_comment, facebook_share, videoViews, and impression, instead of dedicated TikTok counters. Historical counter names replaced by these public names, and counters that are no longer available from network APIs, are intentionally omitted.

Organic Listening

/listening/organic/listening/organic/stats/listening/organic/aggregation

Tellers

clicknew_leadquantityamountpaywall_viewpaywall_unlockedpaywall_clickpaywall_subscribe_clickpaywall_login_clicksubscription_completecomment_countvideo_viewsview_in_stockview_out_of_stockpriceprice_variationlow_pricehigh_priceratingreview_countstock

Opmerking: Use these names for standard Organic Listening counter filters and sorts. Legacy Organic counters are intentionally excluded from the public API surface.

Shortlinks

/shortlinks/shortlinks/:shortlinkId/shortlinks/stats/shortlinks/authors/shortlinks/brands

Tellers

click

Opmerking: Shortlink counter endpoints only expose shortlink counters and reject post counters.

Accounts

/accounts/accounts/stats

Tellers

follower_count

Opmerking: Use the full counter path on Accounts endpoints, for example sort=-counters.total.follower_count or filters=counters.graph.counter:follower_count. The counter sort shorthand (sort=-follower_count) also resolves. The documented name is resolved to the stored account counter internally; historical internal counter names are intentionally omitted. Post counters such as engagement, reach, or videoViews are invalid for Accounts.

4.Fouten

Baseer de afhandeling op de HTTP-statuscode in plaats van op de tekst van de foutmelding. Statuscodes hebben hun standaard HTTP-betekenis.

StatusBetekenis
200OKHet verzoek is geslaagd.
400Bad requestDe payload of de queryparameters waren ongeldig opgebouwd of hebben de validatie niet doorstaan.
401UnauthorizedHet Authorization Bearer-token ontbreekt of is ongeldig. Controleer de waarde van het token of vernieuw het in de back office voordat u de aanroep opnieuw verstuurt.
403ForbiddenHet API-token is geldig, maar heeft geen toestemming voor deze resource.
404Not foundDe resource bestaat niet of is niet zichtbaar voor uw bedrijf.
409ConflictEen PUT /posts/bulk-verzoek over één bericht bevat een schedule, publishedAt, shortId of status die niet kan worden toegepast, of een bericht in het verzoek wijzigt een publishedAt, postType of korte link die niet meer kan veranderen. De melding geeft de reden en er wordt niets bijgewerkt.
423LockedEen bericht in een PUT /posts/bulk-verzoek is minder dan 3 seconden geleden bijgewerkt of wordt bewerkt of gepubliceerd. Als de Retry-After-header aanwezig is, probeer het dan opnieuw na dat aantal seconden; probeer het anders over een paar seconden opnieuw.
429Too many requestsEen limiet is bereikt. Als de Retry-After-header aanwezig is, wacht dan dat aantal seconden voordat u het opnieuw probeert.
500Server errorOnverwachte serverfout. Probeer idempotente leesverzoeken opnieuw met backoff.

Foutantwoorden bevatten een JSON-body die het probleem beschrijft, maar de HTTP-statuscode is leidend: bouw de foutafhandeling rond de statuscode, niet rond de tekst van de melding.

Richtlijnen voor afhandeling

  • Behandel elke status buiten 2xx als een mislukking en lees de JSON-body voor context.
  • Controleer bij 401 de waarde van het API-token, vernieuw het zo nodig en verstuur het verzoek opnieuw.
  • Lees bij 409 de reden in de melding, corrigeer het verzoek en verstuur het meteen opnieuw: een verzoek waarin geen enkel bericht is bijgewerkt, houdt geen vergrendeling vast.
  • Wacht bij 423 het aantal seconden van de Retry-After-header, maximaal 3 na een voltooide update, en verstuur dan hetzelfde verzoek opnieuw. Een 423 zonder Retry-After betekent dat het bericht wordt gepubliceerd: probeer het over een paar seconden opnieuw.
  • Wacht bij een 429 door de limiet het aantal seconden van de Retry-After-header, ook verzonden als RateLimit-Reset, voordat u het opnieuw probeert. Een 429 door het YouTube-quotum op playlist-endpoints heeft geen Retry-After: probeer het later opnieuw.
  • Probeer bij 5xx idempotente leesverzoeken opnieuw met exponentiële backoff.

Naslag

5.Brands

2 endpoints

Read the brands attached to the authenticated company. Brand IDs are required by publishing and shortlink workflows.

GET/brands/:brandIdBearer vereist

5.2.Get a brand

Return one brand with optional embedded configuration used for publishing, shortlinks, smart images, and URL parameters.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.
embedstringCan embed urlParameters, domains, geoblocking, smart image configs, smart message configs, and URLs to stalk.

Velden van het antwoord

VeldTypeBeschrijving
idintUnique brand ID.
namestringBrand name.
shortDomainstringBrand short domain.
domainsBrandDomain[]Configured brand domains when embedded.
urlParametersobject[]URL parameter configuration when embedded.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/brands/1?fields=id,name,shortDomain&embed=domains,urlParameters' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

6.Social accounts

10 endpoints

Read connected social accounts and quota data required before creating or scheduling posts.

GET/social-accounts/:socialAccountIdBearer vereist

6.2.Get a social account

Return one connected social account with publishing metadata.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.

Velden van het antwoord

VeldTypeBeschrijving
idintSocial account ID.
accountIdstringSocial network account/page ID. Pass this value as socialAccount.externalId when creating a post.
namestringAccount display name.
typestringNetwork type.
brandIdintAssociated brand ID.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/social-accounts/42?fields=id,name,type,accountId,brandId' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/social-accounts/publishing-quotaBearer vereist

6.3.Get publishing quota

Return publishing quota information for selected social accounts before scheduling posts.

Queryparameters

VeldTypeBeschrijving
socialAccountsstringComma-separated network|externalId pairs, using type and accountId from the social accounts endpoints (e.g. facebook|123456789,twitter|987654321). Internal social account IDs are not accepted: one malformed item returns 400 Bad Request for the whole request.

Velden van het antwoord

VeldTypeBeschrijving
totalintNumber of social accounts returned in rows.
rowsobject[]Publishing quota of each requested social account. Accounts not found in your company, or whose quota cannot be fetched from the network, are omitted and the request still succeeds.
->externalIdstringAccount ID on the network, as sent in socialAccounts.
->typestringNetwork type, as sent in socialAccounts.
->quotaint|nullPublishing limit reported by the network: the total number of posts allowed in the network's rolling window for Instagram and Threads, or 0 for TikTok when posting is currently blocked. Null when the network reports no per-account limit (all other networks, and TikTok when posting is allowed). The value may be cached for up to 10 minutes.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/social-accounts/publishing-quota?socialAccounts=facebook%7C123456789,twitter%7C987654321' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/social-accounts/youtube/playlistsBearer vereist

6.4.Get YouTube playlists

Return the playlists of connected YouTube social accounts, to choose the `youtube.playlistIds` of a YouTube post. Playlist items (videos) are not returned.

  • IDs that are not YouTube social accounts of your company are silently left out of the response. When YouTube rejects the request for one account, its entry has an empty playlists array and an error message, and the other accounts are still returned.
  • Playlists of every visibility are returned, with their privacyStatus. They are cached for one hour per account. The cache is cleared after a create, update, or delete through this API; a change made in YouTube Studio appears after the cache expires or with force=true. A playlist created moments ago can be missing from the list until YouTube exposes it: read the list again with force=true.

Queryparameters

VeldTypeBeschrijving
socialAccounts*stringComma-separated Nonli social account IDs: the `id` field returned by GET /social-accounts, not the network `accountId`. Any other query parameter, such as page, size, or filters, returns 400 Bad Request.
forceboolBypass the one-hour cache and read the playlists from YouTube.Standaard: false

Velden van het antwoord

VeldTypeBeschrijving
YouTubeAccountPlaylists[]YouTubeAccountPlaylists[]One entry per requested ID that is a YouTube social account of your company. The response is a JSON array, not a paginated { total, rows } object.
->socialAccountIdintNonli social account ID.
->playlistsobject[]Playlists of the account.
->->idstringYouTube playlist ID, to send in youtube.playlistIds.
->->titlestringPlaylist title.
->->descriptionstringPlaylist description.
->->thumbnailUrlstringPlaylist thumbnail URL.
->->itemCountintNumber of videos in the playlist.
->->privacyStatusstringPlaylist visibility: public, unlisted, or private.
->errorstringPresent only when the playlists of this account could not be read from YouTube.

Voorbeeld

bash
1# 1. Find the Nonli IDs of your YouTube social accounts.
2curl --location 'https://api.nonli.com/v2.1/social-accounts?filters=type:youtube&fields=id,name,type' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN'
4
5# 2. Read the playlists of those accounts, for example IDs 42 and 43.
6curl --location 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists?socialAccounts=42,43' \
7 --header 'Authorization: Bearer YOUR_API_TOKEN'

Voorbeeld van een antwoord

json
1[
2 {
3 "socialAccountId": 42,
4 "playlists": [
5 {
6 "id": "PLxxxxxxxxxxxxxxxx",
7 "title": "Interviews",
8 "description": "",
9 "thumbnailUrl": "https://i.ytimg.com/vi/xxxxxxxxxxx/hqdefault.jpg",
10 "itemCount": 12,
11 "privacyStatus": "public"
12 }
13 ]
14 },
15 {
16 "socialAccountId": 43,
17 "playlists": [],
18 "error": "Error message returned for this account"
19 }
20]
POST/social-accounts/youtube/playlistsBearer vereist

6.5.Create a YouTube playlist

Create a playlist on the channel of a connected YouTube social account. The API answers 201 Created with the new playlist. The API-token role must be allowed to manage social accounts. An unknown socialAccountId, or one that is not a YouTube account, returns 404 Not Found.

  • Each call counts against the 24-hour limit of its own endpoint, including calls that fail. When the YouTube quota is exhausted the API returns 429 with a message such as "The YouTube quota is reached, please retry later."; this 429 does not come from the Nonli rate limiter and carries no Retry-After header. When the YouTube authorization of the account has expired the API returns 400 and the account must be reconnected.
  • A playlist created through this API can be updated and deleted right away, even before YouTube exposes it everywhere. During that short delay the update response has a null itemCount and the playlist items endpoint returns an empty page.
Limiet20 calls every 24 hours per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 21st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
socialAccountId*intNonli ID of the YouTube social account that owns the playlist: the `id` field returned by GET /social-accounts, not the network `accountId`.
title*stringPlaylist title, 1 to 150 characters.
descriptionstringPlaylist description, up to 5,000 characters.
privacyStatusstringPlaylist visibility: public, unlisted, or private.Standaard: private

Velden van het antwoord

VeldTypeBeschrijving
idstringYouTube playlist ID.
titlestringPlaylist title.
descriptionstringPlaylist description.
thumbnailUrlstringPlaylist thumbnail URL.
itemCountintNumber of videos in the playlist.
privacyStatusstringPlaylist visibility: public, unlisted, or private.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "socialAccountId": 42,
6 "title": "Interviews",
7 "description": "Every interview of the season",
8 "privacyStatus": "unlisted"
9 }'

Voorbeeld van een antwoord

json
1{
2 "id": "PLxxxxxxxxxxxxxxxx",
3 "title": "Interviews",
4 "description": "Every interview of the season",
5 "thumbnailUrl": "https://i.ytimg.com/img/no_thumbnail.jpg",
6 "itemCount": 0,
7 "privacyStatus": "unlisted"
8}
PUT/social-accounts/youtube/playlists/:playlistIdBearer vereist

6.6.Update a YouTube playlist

Change the title, description, or visibility of a playlist of a connected YouTube social account. Fields left out keep their current value. The API answers with the updated playlist.

  • Each call counts against the 24-hour limit of its own endpoint, including calls that fail. When the YouTube quota is exhausted the API returns 429 with a message such as "The YouTube quota is reached, please retry later."; this 429 does not come from the Nonli rate limiter and carries no Retry-After header. When the YouTube authorization of the account has expired the API returns 400 and the account must be reconnected.
  • A playlist that does not exist or belongs to another channel returns 404 Not Found.
  • A playlist created through this API can be updated and deleted right away, even before YouTube exposes it everywhere. During that short delay the update response has a null itemCount and the playlist items endpoint returns an empty page.
Limiet20 calls every 24 hours per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 21st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
socialAccountId*intNonli ID of the YouTube social account that owns the playlist: the `id` field returned by GET /social-accounts, not the network `accountId`.
titlestringNew playlist title, 1 to 150 characters.
descriptionstringNew playlist description, up to 5,000 characters.
privacyStatusstringNew playlist visibility: public, unlisted, or private.

Velden van het antwoord

VeldTypeBeschrijving
idstringYouTube playlist ID.
titlestringPlaylist title.
descriptionstringPlaylist description.
thumbnailUrlstringPlaylist thumbnail URL.
itemCountint|nullNumber of videos in the playlist; null while YouTube does not return a playlist that was just created.
privacyStatusstringPlaylist visibility: public, unlisted, or private.

Voorbeeld

bash
1curl --location --request PUT 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists/PLxxxxxxxxxxxxxxxx' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "socialAccountId": 42,
6 "title": "Interviews 2026",
7 "privacyStatus": "public"
8 }'
DELETE/social-accounts/youtube/playlists/:playlistIdBearer vereist

6.7.Delete a YouTube playlist

Delete a playlist of a connected YouTube social account. The videos themselves are not deleted. The API answers 204 No Content.

  • Each call counts against the 24-hour limit of its own endpoint, including calls that fail. When the YouTube quota is exhausted the API returns 429 with a message such as "The YouTube quota is reached, please retry later."; this 429 does not come from the Nonli rate limiter and carries no Retry-After header. When the YouTube authorization of the account has expired the API returns 400 and the account must be reconnected.
  • A playlist that does not exist or belongs to another channel returns 404 Not Found.
  • A playlist created through this API can be updated and deleted right away, even before YouTube exposes it everywhere. During that short delay the update response has a null itemCount and the playlist items endpoint returns an empty page.
Limiet20 calls every 24 hours per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 21st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
socialAccountId*intNonli ID of the YouTube social account that owns the playlist: the `id` field returned by GET /social-accounts, not the network `accountId`. Send it in the query string, without a request body.

Voorbeeld

bash
1curl --location --request DELETE 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists/PLxxxxxxxxxxxxxxxx?socialAccountId=42' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/social-accounts/youtube/playlists/:playlistId/itemsBearer vereist

6.8.List the videos of a YouTube playlist

Return one page of the videos of a YouTube playlist, in playlist order. The result is read from YouTube on each call and is not cached.

  • Page through the playlist with pageToken: send the nextPageToken of the previous response until it is null. An unknown or inaccessible playlist returns 404 Not Found; a playlist created through this API moments ago returns an empty page instead.
  • When the YouTube quota is exhausted the API returns 429 with a message such as "The YouTube quota is reached, please retry later."; this 429 does not come from the Nonli rate limiter and carries no Retry-After header. When the YouTube authorization of the account has expired the API returns 400 and the account must be reconnected.

Queryparameters

VeldTypeBeschrijving
socialAccountId*intNonli ID of the YouTube social account that owns the playlist: the `id` field returned by GET /social-accounts, not the network `accountId`.
sizeintNumber of videos per page, from 1 to 50.Standaard: 50
pageTokenstringToken of the page to read, taken from nextPageToken.

Velden van het antwoord

VeldTypeBeschrijving
itemsobject[]Videos of the requested page.
->idstringPlaylist item ID, to send as itemId when moving the video.
->videoIdstringYouTube video ID.
->positionintZero-based position of the video in the playlist.
->titlestringVideo title.
->addedAtdateDate the video was added to the playlist.
->videoPublishedAtdatePublication date of the video.
->privacyStatusstringVisibility of the video.
nextPageTokenstring|nullToken of the next page, or null on the last page.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists/PLxxxxxxxxxxxxxxxx/items?socialAccountId=42&size=50' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

Voorbeeld van een antwoord

json
1{
2 "items": [
3 {
4 "id": "UExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
5 "videoId": "xxxxxxxxxxx",
6 "position": 0,
7 "title": "Interview of the week",
8 "addedAt": "2026-10-01T09:30:00Z",
9 "videoPublishedAt": "2026-09-30T16:00:00Z",
10 "privacyStatus": "public"
11 }
12 ],
13 "nextPageToken": null
14}
PUT/social-accounts/youtube/playlists/:playlistId/items/:itemIdBearer vereist

6.9.Move a video in a YouTube playlist

Move a video to another position of a YouTube playlist. The API answers with the moved item and its new position.

  • Each call counts against the 24-hour limit of its own endpoint, including calls that fail. When the YouTube quota is exhausted the API returns 429 with a message such as "The YouTube quota is reached, please retry later."; this 429 does not come from the Nonli rate limiter and carries no Retry-After header. When the YouTube authorization of the account has expired the API returns 400 and the account must be reconnected.
  • The playlist must be sorted manually in YouTube: otherwise the call returns 400 Bad Request with a message such as "This playlist is not sorted manually in YouTube: set its order to manual before moving a video." A position beyond the end of the playlist also returns 400, and an unknown playlist or item returns 404 Not Found.
Limiet20 calls every 24 hours per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 21st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
socialAccountId*intNonli ID of the YouTube social account that owns the playlist: the `id` field returned by GET /social-accounts, not the network `accountId`.
position*intNew zero-based position of the video, from 0 to 4999.

Velden van het antwoord

VeldTypeBeschrijving
idstringPlaylist item ID, to send as itemId when moving the video.
videoIdstringYouTube video ID.
positionintZero-based position of the video in the playlist.
titlestringVideo title.
addedAtdateDate the video was added to the playlist.
videoPublishedAtdatePublication date of the video.
privacyStatusstringVisibility of the video.

Voorbeeld

bash
1# itemId is the id of the item returned by the playlist items endpoint, not the video ID.
2curl --location --request PUT 'https://api.nonli.com/v2.1/social-accounts/youtube/playlists/PLxxxxxxxxxxxxxxxx/items/UExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
3 --header 'Content-Type: application/json' \
4 --header 'Authorization: Bearer YOUR_API_TOKEN' \
5 --data '{
6 "socialAccountId": 42,
7 "position": 0
8 }'
GET/social-accounts/pinterest/boardsBearer vereist

6.10.Get Pinterest boards

Return the boards of connected Pinterest social accounts, to choose the `pinterest.boardId` of a Pinterest post.

  • IDs that are not Pinterest social accounts of your company are silently left out of the response. When Pinterest rejects the request for one account, its boards array is empty.
  • Boards are cached for one hour per account; set force=true to read them from Pinterest again.

Queryparameters

VeldTypeBeschrijving
socialAccounts*stringComma-separated Nonli social account IDs: the `id` field returned by GET /social-accounts, not the network `accountId`. Any other query parameter, such as page, size, or filters, returns 400 Bad Request.
forceboolBypass the one-hour cache and read the boards from Pinterest.Standaard: false

Velden van het antwoord

VeldTypeBeschrijving
PinterestAccountBoards[]PinterestAccountBoards[]One entry per requested ID that is a Pinterest social account of your company. The response is not a paginated { total, rows } object. Send only valid Pinterest account IDs: when an ID placed before a valid one is left out, the entries currently come back as a JSON object keyed by position instead of an array.
->socialAccountIdintNonli social account ID.
->boardsobject[]Boards of the account, as returned by Pinterest, including `id` (to send in pinterest.boardId) and `name`.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/social-accounts/pinterest/boards?socialAccounts=42' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

7.Posts

15 endpoints

Search, create, update, and delete social posts. Bulk write endpoints accept arrays so integrations can synchronize several posts at once.

To export the posts of a connected network:

  1. 1Call GET /posts with filters=socialAccount.type:youtube;publishedAt:2026-06-01T00:00:00Z..2026-07-01T00:00:00Z, replacing the network and the range. The upper bound of the range is excluded. A brandId filter is optional: without it, the posts of every account the token can access are returned.
  2. 2Request only the fields you need with fields, set size=100, and increase page from 0 until a page returns fewer rows than size. total gives the number of matching posts.
  3. 3Keep (page + 1) × size at or below 10,000: for a larger export, split the period into shorter publishedAt ranges and paginate each one.

Berichten van uw gekoppelde accounts of Social Listening-berichten? Lees de handleiding over Social Listening

GET/posts/:postIdBearer vereist

7.2.Get a post

Return one post by ID with optional filters and field selection.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.
filtersstringOptional filters used to optimize lookup, such as createdAt.
embedstringOptional related data to embed.

Velden van het antwoord

VeldTypeBeschrijving
idstringPost ID.
createdAtdateCreation date.
publishedAtdatePublication date.
messagestringPost message.
postTypestringPost type.
socialAccountSocialAccountTarget social account.
statusintPost status.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/4283ab2d-e3dd-7b1a-7cd6-bbcc71e1xxxx?fields=id,message,postType,publishedAt,socialAccount,status' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/categoriesBearer vereist

7.3.Get post categories

Return category aggregations used by post filters and dashboards.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of categories found.
rows.keystringCategory value.
rows.doc_countintNumber of posts in the category.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/categories?filters=brandId:1&size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/brandsBearer vereist

7.4.Get post brands

Return brand aggregations for posts visible to the API token role.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of brands found.
rows.keystringBrand identifier or name.
rows.doc_countintNumber of posts for the brand.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/brands?filters=publishedAt:-30%20days..now&size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/usersBearer vereist

7.5.Get post users

Return user aggregations for post author and collaboration filters.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of users found.
rows.keystringUser identifier or name.
rows.doc_countintNumber of posts for the user.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/users?filters=brandId:1&size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/languagesBearer vereist

7.6.Get post languages

Return language aggregations for post filters.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of languages found.
rows.keystringLanguage code.
rows.doc_countintNumber of posts for the language.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/languages?filters=brandId:1&size=50' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/histogramBearer vereist

7.7.Get post histogram

Return time-bucketed post counts for graphing.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
  • Without a status value in filters, posts of every status except 404 (deleted) and 410 (outdated) are counted, including drafts, scheduled posts, posts awaiting review, and failed publications. For figures consistent with published content, add filtersOr=status:200,203,204: published, publishing, and waiting to retry, the statuses of the "Published" group in the Nonli back office.
  • A brandId value in filters or filtersOr selects the posts of the social accounts currently attached to that brand, whether they were published through Nonli or imported from the network: the brandId stored on each post is not used, so imported posts are included and an account moved to another brand takes its history with it. excludes=brandId: still tests the stored field and does not exclude imported posts.

Queryparameters

VeldTypeBeschrijving
qstringFull-text search query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.
fieldstringDate field used to build the buckets.Standaard: publishedAt
baseIntervalstringBucket interval: minute, hour, day, week, month, or year.Standaard: year
searchForMinPointsCountboolWhen true, the API retries with the next smaller interval while the histogram has fewer than minPointsCount buckets. Set false to keep baseInterval.Standaard: true
minPointsCountintMinimum number of buckets sought when searchForMinPointsCount is true.Standaard: 10
keyAsDateboolReturn bucket keys as dates. Set false to receive millisecond timestamps.Standaard: true
timezonestringTimezone of the buckets, as an ISO 8601 UTC offset (+01:00) or a TZ database name (Europe/Paris).

Velden van het antwoord

VeldTypeBeschrijving
totalintNumber of buckets.
intervalstringInterval actually used for the buckets.
rowsobject[]Histogram buckets.
rows.keystringBucket date, or millisecond timestamp when keyAsDate is false.
rows.valueintNumber of posts in the bucket.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/histogram?filters=brandId:1;publishedAt:2026-05-01T00:00:00Z..2026-05-28T00:00:00Z&filtersOr=status:200,203,204&field=publishedAt&baseInterval=day&searchForMinPointsCount=false' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/aggregationBearer vereist

7.8.Get post aggregation

Return generic aggregations for post dashboards and filter facets.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
  • Without a status value in filters, posts of every status except 404 (deleted) and 410 (outdated) are counted, including drafts, scheduled posts, posts awaiting review, and failed publications. For figures consistent with published content, add filtersOr=status:200,203,204: published, publishing, and waiting to retry, the statuses of the "Published" group in the Nonli back office.
  • A brandId value in filters or filtersOr selects the posts of the social accounts currently attached to that brand, whether they were published through Nonli or imported from the network: the brandId stored on each post is not used, so imported posts are included and an account moved to another brand takes its history with it. excludes=brandId: still tests the stored field and does not exclude imported posts.
  • To list the custom tags in use, call GET /posts/aggregation?fields=customTag with a brandId filter: each row is a tag with its number of posts. Tags are case-sensitive. To read the list configured on a brand, call GET /brands/:brandId?fields=id,name,customTags,forceCustomTags.

Queryparameters

VeldTypeBeschrijving
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.
sizeintMaximum number of buckets to return.Standaard: 1000
fieldsstringField to aggregate, for example customTag or socialAccount.type. Several comma-separated fields are aggregated together, with their values joined by "|" in each bucket key.
fieldstringField to aggregate when fields is not set.
intervalstringDate interval, to aggregate a date field as a date histogram.
timezonestringTimezone of the date buckets.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of aggregation buckets.
rows.keystringBucket key.
rows.valueintNumber of posts in the bucket.

Voorbeeld

bash
1# Posts per network of a brand.
2curl --location 'https://api.nonli.com/v2.1/posts/aggregation?field=socialAccount.type&filters=brandId:1&filtersOr=status:200,203,204&size=20' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN'
4
5# Custom tags in use on a brand, with their number of posts.
6curl --location 'https://api.nonli.com/v2.1/posts/aggregation?fields=customTag&filters=brandId:1&filtersOr=status:200,203,204' \
7 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/statsBearer vereist

7.9.Get post stats

Return aggregated post performance statistics for dashboard widgets.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
  • This endpoint applies no default status filter: without a status filter, posts of every status are counted, including drafts, scheduled posts, failed publications, and deleted (404) or outdated (410) posts. For figures consistent with published content, add filtersOr=status:200,203,204: published, publishing, and waiting to retry, the statuses of the "Published" group in the Nonli back office.
  • A brandId value in filters or filtersOr selects the posts of the social accounts currently attached to that brand, whether they were published through Nonli or imported from the network: the brandId stored on each post is not used, so imported posts are included and an account moved to another brand takes its history with it. excludes=brandId: still tests the stored field and does not exclude imported posts.

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
pageintZero-based page number.Standaard: 0
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
sortstringSort expression. Prefix a field with "-" for descending order. Counter-backed endpoints can sort by counters.total.<field> or by the counter shorthand itself, for example sort=-engagement on post/social data or sort=-click on organic data.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
fieldsstringComma-separated fields to include in each returned item.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
rowsobject[]Stat rows returned by the selected filters.
totalintTotal matching posts or stats rows.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/stats?filters=brandId:1;publishedAt:-30%20days..now&fields=counters.total&size=50' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
POST/posts/checkBearer vereist

7.10.Check post content

Validate post content before publishing. The BO uses this endpoint to surface publication warnings.

Bodyparameters

VeldTypeBeschrijving
messagestringPost message to validate.
titlestringPost title.
descriptionstringPost description.
socialAccount.typestringTarget social network type.
brandIdintBrand ID.

Velden van het antwoord

VeldTypeBeschrijving
validboolWhether the post content passed validation.
warningsobject[]Warnings returned by publication checks.
errorsobject[]Blocking validation errors.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/check' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "brandId": 1,
6 "message": "Post copy",
7 "socialAccount.type": "linkedin"
8 }'
GET/posts/tagsBearer vereist

7.11.Get post tags

Return the most used values of the post `tag` field that match a prefix, for autocomplete and reporting filters.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
  • Only published posts (status 200) are counted.
  • This endpoint aggregates the tag field, not customTag: tags written in customTag are not returned. To list the custom tags in use, call GET /posts/aggregation?fields=customTag with a brandId filter: each row is a tag with its number of posts. Tags are case-sensitive. To read the list configured on a brand, call GET /brands/:brandId?fields=id,name,customTags,forceCustomTags.
  • Prefix matching is case-sensitive.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintCount of results to return.Standaard: 10
prefix*stringTag prefix, case-sensitive. The parameter must be present; send it empty (prefix=) to match every tag.
selected*stringAlready selected tags, comma separated: only posts that carry every selected tag are counted, and the selected tags are removed from the results. The parameter must be present; send it empty (selected=) when no tag is selected.
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of items found.
rows.keystringTag.
rows.doc_countintNumber of published posts where the tag was found.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/tags?prefix=&selected=&filters=brandId:1;publishedAt:-30%20days..now&size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/posts/topicsBearer vereist

7.12.Get post topics

Return the most used post topics that match a prefix, for autocomplete and reporting filters.

  • Post-backed endpoints accept the documented post counters in counter filters and counter sorts, and responses echo the counter names the request used. Historical counter names replaced by public counter names are intentionally omitted.
  • Only published posts (status 200) are counted. Prefix matching is case-sensitive.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintCount of results to return.Standaard: 10
prefix*stringTopic prefix, case-sensitive. The parameter must be present; send it empty (prefix=) to match every topic.
selected*stringAlready selected topics, comma separated: only posts that carry every selected topic are counted, and the selected topics are removed from the results. The parameter must be present; send it empty (selected=) when no topic is selected.
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of items found.
rows.keystringTopic.
rows.doc_countintNumber of published posts where the topic was found.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/topics?prefix=&selected=&filters=brandId:1;publishedAt:-30%20days..now;socialAccount.type:facebook&size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
POST/posts/bulkBearer vereist

7.13.Create posts in bulk

Create one or more posts: submit them for review, publish them immediately, or schedule them. The API-token role must grant `post.write` and access to every requested brand and social account.

  • Post status is constrained by the API-token role. review always remains pending validation, and read access to the target is sufficient to create a post for review. A publish request is automatically downgraded to review when the role cannot publish directly. Tokens without post.write or access to the requested resources are rejected.
  • The creator identity is server-managed. Posts created with a Bearer token use API <token name> as author and have no userId. Client-supplied author identity fields are ignored, so an API integration cannot impersonate a Nonli user.
  • When the brand has forceCustomTags enabled, a request that attaches a customTag value absent from the brand customTags list fails as a whole with 400 Bad Request, and no post is written. Matching is exact and case-sensitive. Tags already stored on an updated post are accepted. Add the tag to the brand list first, with PUT /brands/:brandId and the complete customTags array, which replaces the stored list.
  • When a post published through Nonli has also been imported from the network as a separate post, Nonli removes the imported copy once the publication succeeds, so the post appears once. Duplicates created before this behavior shipped are not removed.
  • Build a thread sequentially. Set thread.activated=true on every segment. The root omits isChild, parent, and origin; every later segment sets isChild=true, parent to the immediately previous segment ID, and origin to the root ID. For the first child, parent and origin therefore have the same root ID. After adding each child, read the root and verify its ordered thread.children list: a successful HTTP response alone does not prove that the chain is complete.
  • On networks with first-comment support, put the article link in post.comment. Threads and Bluesky do not publish a native first comment, so a hand-built chain must instead attach the shortlink to the root with shortlink.mappingId and put the resolved public URL only in the final segment message. Create that final segment without the URL, update it with the root response values https://ROOT_SHORT_DOMAIN/ROOT_SHORT_ID, then read the root and final segment back before publication. Do not also place that URL in a root first comment.
  • On Threads and Bluesky, Nonli can automatically convert an active first comment into the first child when the root has neither an activated thread nor existing children. [SHORTLINK] is expanded only during that conversion and only when the first comment has a shortlink. It is not expanded in segments created directly through /posts/bulk; hand-built segments must contain the resolved URL.
  • Validate every segment against its destination network before creating the chain. Threads currently allows 500 characters per segment; Bluesky allows 300 graphemes. Mentions and links contribute to those limits, including the resolved shortlink added to the final segment.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
post*Post[]Array of post objects.
->brandId*intBrand ID used to create the post.
->postType*stringNonli post type: text, video, link, photo, album, flying, reel, document, etc.
->socialAccountobjectTarget connected social account. Required for standard posts sent for review or publication; omit only when the post type has an implicit or special target.
->->externalIdstringNetwork ID of the target connected social account. Use the accountId returned by GET /social-accounts.
->->publisherIdstringPublisher ID used when the target account publishes through another account.
->->typestringTarget social network type, such as facebook, instagram, linkedin, or tiktok.
->->subTypestringTarget account subtype, such as page or group.
->statusstringCreation mode: review or publish. API tokens cannot use draft: the whole request fails with 400; use review. The default depends on the token role permissions.
->shortlinkobjectRelated shortlink. Required when postType is flying.
->->mappingIdstringRelated shortlink ID.
->messagestringPost message.
->titlestringDisplayed post title.
->descriptionstringLink or media description.
->commentobjectOptional first comment. On networks with native first-comment support, put the article link in this comment. On Threads and Bluesky, an active comment can be converted to the first thread child when the root has no active thread or children.
->->activatedboolSet true to publish or convert the first comment.
->->messagestringFirst-comment text. `[SHORTLINK]` is resolved only during the documented automatic comment-to-thread conversion.
->threadobjectThread relationship. Create the root first, then create each child after the previous segment succeeds.
->->activatedboolSet true on the root and every child to activate the thread relationship.
->->isChildboolSet true on child segments. Omit on the root.
->->parentstringUUID of the immediately previous segment. For the first child, this is the root UUID.
->->originstringUUID of the root segment. It remains the same for every child.
->scheduleobjectOptional publication schedule. With status publish, omit this object to publish immediately.
->->startDatedateScheduled publication start date.
->->endDatedateOptional end of the scheduling optimization range.
->imageobject[]Post images.
->->fontanSlugstringFontan image slug.
->->urlstringExternal image URL.
->videoobject[]Post videos.
->->mappingIdstringUploaded video ID.

Velden van het antwoord

VeldTypeBeschrijving
Post[]Post[]Created posts with status and additional values.
->idstringCreated post UUID.
->authorstringServer-managed author. Bearer-created posts use API followed by the token name.
->userIdint|nullNull for posts created with an API token.
->statusintStored status. Common values are 201 for draft, 210 for awaiting review, 202 for pending or scheduled publication, 203 for publishing, and 200 for published. A publish request may return 210 when the token role causes a review downgrade.
->shortDomainstring|nullDomain of the generated public shortlink. Combine with shortId when resolving the URL for a hand-built thread.
->shortIdstring|nullPath identifier of the generated public shortlink.
->threadobject|nullStored thread relationship.
->->activatedboolWhether the thread relationship is active.
->->isChildboolWhether this post is a child segment.
->->parentstring|nullUUID of the immediately previous segment.
->->originstring|nullUUID of the root segment.
->->childrenstring[]On the root, ordered UUIDs of every descendant segment, from the first child to the final segment.

Voorbeeld

bash
1# A. Create an ordinary post for review.
2curl --location 'https://api.nonli.com/v2.1/posts/bulk' \
3 --header 'Content-Type: application/json' \
4 --header 'Authorization: Bearer YOUR_API_TOKEN' \
5 --data '{
6 "post": [{
7 "brandId": 1,
8 "postType": "text",
9 "message": "Hello from the Nonli API",
10 "status": "review",
11 "socialAccount": {
12 "externalId": "SOCIAL_ACCOUNT_ACCOUNT_ID",
13 "type": "facebook"
14 }
15 }]
16 }'
17
18# B. Build a three-segment thread.
19# 1. Create the root with the shortlink mapping.
20curl --location 'https://api.nonli.com/v2.1/posts/bulk' \
21 --header 'Content-Type: application/json' \
22 --header 'Authorization: Bearer YOUR_API_TOKEN' \
23 --data '{
24 "post": [
25 {
26 "brandId": 1,
27 "postType": "text",
28 "message": "The opening segment",
29 "status": "review",
30 "shortlink": { "mappingId": "SHORTLINK_MAPPING_ID" },
31 "socialAccount": {
32 "externalId": "SOCIAL_ACCOUNT_ACCOUNT_ID",
33 "type": "threads"
34 },
35 "thread": { "activated": true }
36 }
37 ]
38 }'
39
40# Save the returned id as ROOT_POST_ID and its shortDomain/shortId values.
41# 2. Create the middle segment. The first child's parent is also the origin.
42curl --location 'https://api.nonli.com/v2.1/posts/bulk' \
43 --header 'Content-Type: application/json' \
44 --header 'Authorization: Bearer YOUR_API_TOKEN' \
45 --data '{
46 "post": [{
47 "brandId": 1,
48 "postType": "text",
49 "message": "The middle segment",
50 "status": "review",
51 "socialAccount": { "externalId": "SOCIAL_ACCOUNT_ACCOUNT_ID", "type": "threads" },
52 "thread": {
53 "activated": true,
54 "isChild": true,
55 "parent": "ROOT_POST_ID",
56 "origin": "ROOT_POST_ID"
57 }
58 }]
59 }'
60
61# Save the returned id as MIDDLE_POST_ID.
62# Verify that the root lists the first child before continuing.
63curl --location 'https://api.nonli.com/v2.1/posts?filters=id:ROOT_POST_ID&fields=id,thread' \
64 --header 'Authorization: Bearer YOUR_API_TOKEN'
65
66# 3. Create the final segment without the URL. Its parent is the middle segment.
67curl --location 'https://api.nonli.com/v2.1/posts/bulk' \
68 --header 'Content-Type: application/json' \
69 --header 'Authorization: Bearer YOUR_API_TOKEN' \
70 --data '{
71 "post": [{
72 "brandId": 1,
73 "postType": "text",
74 "message": "Read the complete story:",
75 "status": "review",
76 "socialAccount": { "externalId": "SOCIAL_ACCOUNT_ACCOUNT_ID", "type": "threads" },
77 "thread": {
78 "activated": true,
79 "isChild": true,
80 "parent": "MIDDLE_POST_ID",
81 "origin": "ROOT_POST_ID"
82 }
83 }]
84 }'
85
86# Save the returned id as FINAL_POST_ID and verify the complete child order.
87curl --location 'https://api.nonli.com/v2.1/posts?filters=id:ROOT_POST_ID&fields=id,thread' \
88 --header 'Authorization: Bearer YOUR_API_TOKEN'
89
90# Then add the resolved root URL to the final segment.
91curl --request PUT --location 'https://api.nonli.com/v2.1/posts/bulk' \
92 --header 'Content-Type: application/json' \
93 --header 'Authorization: Bearer YOUR_API_TOKEN' \
94 --data '{
95 "post": [{
96 "id": "FINAL_POST_ID",
97 "message": "Read the complete story: https://ROOT_SHORT_DOMAIN/ROOT_SHORT_ID"
98 }]
99 }'
100
101# 4. Read back the root and final segment. Verify the ordered root thread.children
102# list and the final resolved URL before publication. This GET returns the usual
103# paginated { "total": ..., "rows": [...] } search response.
104curl --location 'https://api.nonli.com/v2.1/posts?filtersOr=id:ROOT_POST_ID,FINAL_POST_ID&fields=id,author,userId,status,postType,message,shortDomain,shortId,thread' \
105 --header 'Authorization: Bearer YOUR_API_TOKEN'

Voorbeeld van een antwoord

json
1[
2 {
3 "id": "ROOT_POST_ID",
4 "author": "API Website publisher",
5 "userId": null,
6 "status": 210,
7 "postType": "text",
8 "message": "The opening segment",
9 "shortDomain": "non.li",
10 "shortId": "abc123",
11 "thread": {
12 "activated": true,
13 "isChild": false,
14 "parent": null,
15 "origin": null,
16 "children": []
17 }
18 }
19]
PUT/posts/bulkBearer vereist

7.14.Update posts in bulk

Update a collection of posts. Send post.id and, when available, createdAt to optimize lookup.

  • Send each post with id, its createdAt when known, and only the fields you change. createdAt locates the post and is never modified; send it as returned by the API, with or without milliseconds. Accepted post fields: socialAccount (externalId, publisherId, type, subType), brandId, tag, customTag, postType, subType, shortlink.mappingId, source.documentId, title, message, description, image, video, media, schedule (startDate, endDate), publishedAt, createdAt, breakingNews, callToAction, shortId, comment (activated, message, pictureUrl), status, isAiGenerated, sponsor, location, geoblocking.country, commentEnabled, duetEnabled, stitchEnabled, madeForKids, threads, visibility, collaborator, pinterest.boardId, youtube.playlistIds, commercialContent, and tiktok.anchor. Each video item accepts url, mappingId, embed, sourceExternalId, title, tag, thumbnail, shareToFeed, isAiGenerated, duration, height, width, and size.
  • Any other key, at any level, makes the whole request fail with 400 Bad Request and an "Unexpected item(s)" message. This includes read-only fields returned by GET /posts/:postId, such as socialAccount fields other than externalId, publisherId, type, and subType, or video[].externalId: do not send back a post object read from the API unchanged.
  • Submitted schedule, publishedAt, shortId, and status values are either applied or rejected with a reason: the API never answers 200 while leaving one of them unapplied. A request that updates a single post and is rejected answers 409 Conflict with the reason in the JSON body, for example {"messages":{"errors":["The publication date (publishedAt) is in the past"]}}, and nothing is updated; an error that has its own status, such as 403, 404, or 423, keeps it. In a request that updates several posts the API answers 200: a rejected post is returned as its id and an error message only, and the other posts are updated. A post whose update failed on an internal error is also returned as its id and error, with a 200 answer, even alone.
  • Scheduling a post that is not published yet: publishedAt alone moves the publication to that date and extends the schedule range to contain it; schedule.startDate without endDate is a fixed publication date; an empty schedule object publishes now. A new publishedAt that is not in the future is rejected with 409, unless the post is published now or the value lies inside a schedule range sent in the same request. An endDate before the startDate, or a schedule ending more than 2 minutes in the past, is rejected with 409. When the schedule of a post that is not published has already elapsed, content changes are saved without rescheduling it, and the returned post carries an error field; a shortId change, a status change, or any update of a post awaiting review is rejected with 409 until a new schedule is sent.
  • On a post already published, a different publishedAt or different schedule dates are rejected with 409. Once publication has started (status 203, 204, or 200), changing postType or the shortlink is rejected with 409 as well. A publishedAt, postType, or shortlink change that can no longer be made fails the whole request with 409, even when the request updates several posts. A status of review that the post can no longer take is rejected with 409; API tokens cannot send draft, which fails the whole request with 400. An invalid shortId, or one already in use, is rejected with 409.
  • When the brand has forceCustomTags enabled, a request that attaches a customTag value absent from the brand customTags list fails as a whole with 400 Bad Request, and no post is written. Matching is exact and case-sensitive. Tags already stored on an updated post are accepted. Add the tag to the brand list first, with PUT /brands/:brandId and the complete customTags array, which replaces the stored list.
  • There is no maximum number of posts per call, and one call counts as one call against the rate limit whatever the number of posts. A very large batch can exceed the server time limits and fail, so split large batches into several calls.
  • After an update has been applied, the same post cannot be updated again for 3 seconds: a request on it during that time fails as a whole with 423 Locked, a Retry-After header giving the real number of seconds left, and a JSON body such as {"messages":{"errors":["The post is being edited, please try again in 3s."]}}. Wait for that number of seconds, then send the request again. While another update of the post is still running, the delay can reach 30 seconds. A request in which no post was updated holds no lock: the corrected request can be sent at once. A post being published also answers 423, without Retry-After: retry a few seconds later.
  • With updatePostOnNetwork=false, Nonli updates the post in Nonli only and sends nothing to the social network: no update of an already published post and no Facebook crosspost preparation. The trace of a published post then records "Update post in Nonli only, not sent to social network" instead of "Update post in social network". The flag concerns the update itself: it does not cancel the publication of a post that is not published yet, which stays in the publication scheduler and is published at its scheduled date. With updatePostOnNetwork=false, YouTube playlists are not changed either.
  • On a published YouTube video updated on the network (updatePostOnNetwork left to true), sending youtube.playlistIds synchronizes the playlists that Nonli manages for this post: the IDs sent now and the IDs previously stored on the post. Nonli adds the video to a requested playlist only when YouTube reports it absent, so no duplicate entry is created, and removes it from a previously stored playlist that is no longer requested. Playlists the video was added to outside Nonli are never changed. Omit youtube.playlistIds to leave playlists untouched; send an empty array to remove the video from the stored playlists. A playlist error does not fail the update: it is recorded in the post trace.
  • Updating a published YouTube video without visibility does not reset it to a default: Nonli sends the visibility stored on the post, or keeps the one YouTube holds when none is stored. On a post already published, the network ID of each video is kept whatever video[].url is sent.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
checkBeforeUpdateboolCheck posts before updating them and skip update if checks fail.
updatePostOnNetworkboolSend the update to the social network. Set false to update the post in Nonli only: nothing is sent to the network.Standaard: true
post*Post[]Array of post objects to update. Only the fields listed in the notes are accepted.
->id*stringPost ID.
->createdAtdateCreation date as returned by the API. It locates the post faster and is never modified.
->shortIdstringNew short ID.
->scheduleobjectScheduling information: startDate and optional endDate. An empty object publishes now. See the notes for the scheduling rules.
->publishedAtdateNew publication date of a post that is not published yet. See the notes for the scheduling rules.
->statusstringreview or publish. A review that the post can no longer take is rejected with 409. API tokens cannot use draft: the whole request fails with 400; use review.
->messagestringUpdated post message.

Velden van het antwoord

VeldTypeBeschrijving
Post[]Post[]One entry per requested post: the updated post with its applied values, or its id and an error message only when its update was rejected.

Voorbeeld

bash
1curl --location --request PUT 'https://api.nonli.com/v2.1/posts/bulk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "post": [
6 {
7 "id": "4283ab2d-e3dd-7b1a-7cd6-bbcc71e1xxxx",
8 "shortId": "new-short-id",
9 "schedule": {}
10 }
11 ]
12 }'
DELETE/posts/bulkBearer vereist

7.15.Delete posts in bulk

Delete a collection of posts. The async flag can be used for background deletion.

Limiet100 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 101st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
post*Post[]Array of posts to delete.
->id*stringPost ID to delete.
->socialAccountExternalIdstringExternal social account ID.
->createdAtdateCreation date of the post to delete.
asyncboolDelete posts asynchronously.Standaard: false

Velden van het antwoord

VeldTypeBeschrijving
Post[]Post[]Deleted posts or per-item errors.

Voorbeeld

bash
1curl --location --request DELETE 'https://api.nonli.com/v2.1/posts/bulk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "post": [
6 {
7 "id": "4283ab2d-e3dd-7b1a-7cd6-bbcc71e1xxxx",
8 "createdAt": "2024-11-26T10:07:36Z"
9 }
10 ]
11 }'

9.Themes

6 endpoints

Create and manage saved theme filters used by listening, publishing, and automation workflows.

GET/themes/:themeIdBearer vereist

9.2.Get a theme

Return one saved theme by ID.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.
embedstringUse embed=roles to include associated roles.

Velden van het antwoord

VeldTypeBeschrijving
idintUnique theme ID.
namestringName.
valuestringJSON-encoded theme filters and section configuration.
queryStringsstringJSON-encoded object of prebuilt query strings for matching sections.
scopestringVisibility scope.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/themes/123?fields=id,name,value,queryStrings,scope&embed=roles' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
POST/themesBearer vereist

9.3.Create a theme

Create a saved theme. The API stores value and queryStrings as JSON-encoded strings and does not derive one from the other.

Limiet20 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 21st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
name*stringTheme name.
typestringTheme type: listening or post.Standaard: listening
scopestringVisibility scope allowed by the API token role: team, bot, or public. Private is reserved for user sessions.Standaard: team
langstringTheme language: en or fr.Standaard: en
value*stringJSON-encoded theme filters and section configuration.
queryStringsstringJSON-encoded object containing the prebuilt query for each enabled section. Supply it when the theme must return results.
rolesAclRoles[]Roles allowed to use a team-scoped theme.

Velden van het antwoord

VeldTypeBeschrijving
idintCreated theme ID.
namestringTheme name.
valuestringJSON-encoded theme filters and section configuration.
queryStringsstringJSON-encoded object of prebuilt query strings.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/themes' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "name": "Editorial performance",
6 "type": "listening",
7 "scope": "team",
8 "lang": "fr",
9 "value": "{\"Sections\":{\"social\":true,\"leaderboard\":true},\"Search\":\"\",\"Filters\":{\"listening\":{\"social\":{\"filters\":{\"publication\":[\"30 days\"],\"socialAccount.type\":\"instagram\"},\"sort\":[{\"field\":\"publishedAt\",\"direction\":\"desc\"}],\"normalization\":false}}}}",
10 "queryStrings": "{\"social\":\"filters=publishedAt:-30 days..now;socialAccount.type:instagram&excludes=subType:story;socialAccount.subType:news,group&qf=title,message,description,category&sort=-publishedAt\",\"leaderboard\":\"filters=publishedAt:-30 days..now;socialAccount.type:instagram&excludes=subType:story;socialAccount.subType:news,group&qf=title,message,description,category&sort=-publishedAt&aggregationField=engagement\"}"
11 }'
PUT/themes/:themeIdBearer vereist

9.4.Update a theme

Update a saved theme. Every field is optional, so a partial update such as a rename alone is valid. When value changes, send the matching queryStrings because the API does not rebuild it automatically.

Limiet100 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 101st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
namestringTheme name.
typestringTheme type: listening or post.
scopestringVisibility scope allowed by the API token role: team, bot, or public. Private is reserved for user sessions.
langstringTheme language: en or fr.
defaultboolWhether this is a default public theme. Restricted to authorized roles.
valuestringJSON-encoded theme filters and section configuration.
queryStringsstringJSON-encoded object containing the prebuilt query for each enabled section.
rolesAclRoles[]Roles allowed to use a team-scoped theme.

Velden van het antwoord

VeldTypeBeschrijving
idintUpdated theme ID.
namestringTheme name.
valuestringJSON-encoded theme filters and section configuration.
queryStringsstringJSON-encoded object of prebuilt query strings.

Voorbeeld

bash
1curl --location --request PUT 'https://api.nonli.com/v2.1/themes/123' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "value": "{\"Sections\":{\"social\":true,\"leaderboard\":true},\"Search\":\"\",\"Filters\":{\"listening\":{\"social\":{\"filters\":{\"publication\":[\"30 days\"],\"socialAccount.type\":\"instagram\"},\"sort\":[{\"field\":\"publishedAt\",\"direction\":\"desc\"}],\"normalization\":false}}}}",
6 "queryStrings": "{\"social\":\"filters=publishedAt:-30 days..now;socialAccount.type:instagram&excludes=subType:story;socialAccount.subType:news,group&qf=title,message,description,category&sort=-publishedAt\",\"leaderboard\":\"filters=publishedAt:-30 days..now;socialAccount.type:instagram&excludes=subType:story;socialAccount.subType:news,group&qf=title,message,description,category&sort=-publishedAt&aggregationField=engagement\"}"
7 }'
DELETE/themes/:themeIdBearer vereist

9.5.Delete a theme

Delete a saved theme.

Limiet50 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 51st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Velden van het antwoord

VeldTypeBeschrijving
deletedboolWhether the theme was deleted.

Voorbeeld

bash
1curl --location --request DELETE 'https://api.nonli.com/v2.1/themes/123' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/themes/rolesBearer vereist

9.6.Get theme roles

Return roles that can be associated with team-scoped themes.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of roles found.
rowsAclRoles[]Available roles.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/themes/roles' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

10.Listening

7 endpoints

Search social-network performance and organic website content signals.

Hoe Social Listening berichten verzamelt en hoe u ze exporteert: lees de handleiding

PUT/listening/organicBearer vereist

10.3.Upsert an organic with videos

Create or update an organic content item keyed by its normalized URL, together with its complete video association collection. Each video can carry its own thumbnail. The API-token role must grant `listening.write`.

  • The video array is the complete association collection of the organic: associations omitted from the request are removed, and an empty array clears the collection. Already imported video assets survive in your company video library and are relinked automatically when a later request references the same sourceId or the same normalized video URL.
  • Each video association must provide exactly one of mappingId (an already imported video asset of your company) or url (an external HTTPS video imported server-side). Video and thumbnail URLs must be HTTPS; they are fetched by the Nonli import pipeline, never by the browser.
  • When at least one external video import is queued, the API returns 202 Accepted instead of 200. The response echoes each association with its import state: linked when the asset is already available, queued while the import runs, or failed.
Limiet300 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 301st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Bodyparameters

VeldTypeBeschrijving
url*stringOrganic URL. Its normalized form is the resource key used for the upsert.
canonicalUrlstringCanonical URL of the organic.
titlestringTitle of the organic.
descriptionstringDescription of the organic.
languagestringLanguage of the organic.
typestringOrganic type: article, product, website, etc.
publishedAtdatePublication date.
modifiedAtdateLast modification date.
tagsstring[]Tags of the organic.
categoriesstring[]Categories of the organic.
videoobject[]Complete video association collection, up to 20 associations. Associations omitted here are removed.
->mappingIdstringIdentifier of an already imported video asset of your company. Provide exactly one of mappingId or url.
->urlstringHTTPS URL of an external video to import. Provide exactly one of mappingId or url.
->sourceIdstringIdentifier of the rendition in your source system, used to relink the same asset on later upserts.
->usagestring[]Intended usages of this rendition: standard or short.
->typestringMIME type of the video.
->widthintWidth in pixels.
->heightintHeight in pixels.
->durationfloatDuration in seconds.
->sizeintSize in bytes.
->thumbnailobjectThumbnail of this video.
->->urlstringHTTPS URL of the thumbnail image, fetched server-side.

Velden van het antwoord

VeldTypeBeschrijving
idstringOrganic identifier.
videoobject[]Resolution state of each video association.
->sourceIdstringRendition identifier as provided.
->urlstringVideo URL as provided.
->mappingIdstringIdentifier of the associated video asset.
->statestringImport state: linked, queued, or failed.

Voorbeeld

bash
1curl --location --request PUT 'https://api.nonli.com/v2.1/listening/organic/' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "url": "https://www.example.com/articles/breaking-news",
6 "title": "Breaking news",
7 "type": "article",
8 "publishedAt": "2026-08-31T09:00:00.000Z",
9 "video": [
10 {
11 "url": "https://cdn.example.com/videos/breaking-news.mp4",
12 "sourceId": "breaking-news-standard",
13 "usage": ["standard"],
14 "type": "video/mp4",
15 "width": 1920,
16 "height": 1080,
17 "duration": 42.5,
18 "thumbnail": { "url": "https://cdn.example.com/videos/breaking-news-thumb.jpg" }
19 }
20 ]
21 }'
GET/listening/organic/:organicIdBearer vereist

10.4.Get organic content

Return one indexed organic content item by ID.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.

Velden van het antwoord

VeldTypeBeschrijving
idstringOrganic content ID.
canonicalUrlstringCanonical URL.
titlestringTitle.
descriptionstringDescription.
publishedAtdatePublication date.
counters.totalCounterTotal[]Aggregated counters.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/listening/organic/8f14e45fceea167a5a36dedd4bea2543?fields=id,title,canonicalUrl,counters.total' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/listening/organic/statsBearer vereist

10.5.Get organic stats

Return aggregated Organic Listening performance statistics.

  • Organic Listening endpoints accept standard Organic Listening counters only. Post counters such as engagement, reach, or videoViews are invalid for Organic Listening and return 400 Bad Request.

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
pageintZero-based page number.Standaard: 0
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
sortstringSort expression. Prefix a field with "-" for descending order. Counter-backed endpoints can sort by counters.total.<field> or by the counter shorthand itself, for example sort=-engagement on post/social data or sort=-click on organic data.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
fieldsstringComma-separated fields to include in each returned item.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
rowsobject[]Stat rows returned by the selected filters.
totalintTotal matching content or stats rows.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/listening/organic/stats?filters=type:article;publishedAt:-30%20days..now&fields=counters.total' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/listening/organic/aggregationBearer vereist

10.6.Get organic aggregation

Return generic aggregations for Organic Listening dashboards and filters.

  • Organic Listening endpoints accept standard Organic Listening counters only. Post counters such as engagement, reach, or videoViews are invalid for Organic Listening and return 400 Bad Request.

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.
fieldstringField to aggregate.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of buckets.
rows.keystringBucket key.
rows.doc_countintBucket count.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/listening/organic/aggregation?field=type&filters=publishedAt:-30%20days..now&size=20' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/listening/organic/suggest/:fieldBearer vereist

10.7.Suggest organic filter values

Return autocomplete suggestions for an Organic Listening field.

Queryparameters

VeldTypeBeschrijving
qstringSuggestion query.
sizeintCount of suggestions to return.Standaard: 10
filtersstringOptional filters to constrain suggestions.

Velden van het antwoord

VeldTypeBeschrijving
rowsobject[]Suggested field values.
rows.keystringSuggested value.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/listening/organic/suggest/title?q=election&size=10' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

11.Leaderboard

3 endpoints

Rank social accounts by an aggregated post counter over any post filter set. Rows combine ranking values with account profile data.

GET/posts/leaderboardBearer vereist

11.1.Get the leaderboard

Return social accounts ranked by an aggregated post counter, with per post type breakdowns and account profile data.

  • aggregationField and additionalAggregationFields accept the documented post counter names, such as engagement, reach, videoViews, click, ctr, overperforming, or monetization. The API resolves each documented name to the stored counter internally; historical internal counter names are intentionally undocumented.
  • Counters built from public network data, such as engagement or videoViews, rank any listened account. Counters that require account ownership automatically restrict the leaderboard to social accounts the API token can access.
  • Leaderboard filters and sorts accept the shorthand fields name, slug, category, and verificationStatus, resolved to the matching socialAccount fields internally.

Queryparameters

VeldTypeBeschrijving
aggregationField*stringDocumented post counter used to rank accounts, for example engagement, reach, videoViews, click, ctr, overperforming, or monetization.
additionalAggregationFieldsstringComma-separated additional documented counters to aggregate per account. Each counter is returned on the row under the requested counter name.
sizeintCount of accounts to return, between 1 and 200.Standaard: 20
pageintZero-based page number.Standaard: 0
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query, for example title,message,description,category.
sortstringRanking direction. Use counters.total.<counter> with the documented counter name, for example sort=-counters.total.engagement. Defaults to descending on aggregationField.
filtersstringAND filters on post fields, such as publishedAt ranges or socialAccount.type. The shorthand fields name, slug, category, and verificationStatus filter the matching socialAccount fields.
filtersOrstringOR filters on post fields.
excludesstringExclude results when a field contains a value.
existsstringComma-separated fields that must exist in matching posts.

Velden van het antwoord

VeldTypeBeschrijving
LeaderboardRow[]LeaderboardRow[]Accounts ranked by the aggregated counter. The response is a JSON array without a total wrapper.
->externalIdstringSocial network account/page ID.
->namestringAccount display name.
->typestringSocial network: facebook, instagram, linkedin, etc.
->slugstringAccount slug.
->picturestringAccount profile picture URL.
->websitestringAccount website.
->docCountintNumber of posts matching the filters for the account.
->valuefloatAggregated aggregationField value across matching posts.
->percentfloatAggregated value relative to the account fan count.
->typesobjectPer post type breakdown keyed by post type, each entry with type, docCount, value, and percent.
->fanCountintAccount fan count.
->followerCountintEstimated follower count.
->verificationStatusstringNetwork verification status.
->createdAtdateAccount creation date.
->countersCounterTotal[]Account counter totals.
-><counter>objectOne entry per additionalAggregationFields counter, keyed by the requested counter name, with value, docCount, and types.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/leaderboard?aggregationField=engagement&additionalAggregationFields=videoViews&filters=publishedAt:-30%20days..now;socialAccount.type:facebook&size=10' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

Voorbeeld van een antwoord

json
1[
2 {
3 "externalId": "339028534278",
4 "name": "Media page",
5 "type": "facebook",
6 "slug": "@mediapage",
7 "picture": "https://...",
8 "docCount": 1240,
9 "value": 458200,
10 "percent": 12.4,
11 "fanCount": 3690000,
12 "followerCount": 3720000,
13 "verificationStatus": "blue_verified",
14 "types": {
15 "link": { "type": "link", "docCount": 980, "value": 310500, "percent": 8.4 },
16 "video": { "type": "video", "docCount": 260, "value": 147700, "percent": 4.0 }
17 },
18 "videoViews": {
19 "externalId": "339028534278",
20 "docCount": 260,
21 "value": 985000,
22 "types": {
23 "video": { "type": "video", "docCount": 260, "value": 985000 }
24 }
25 }
26 }
27]
GET/posts/leaderboard/categoriesBearer vereist

11.3.Get leaderboard categories

Return the per post type counter breakdown for selected leaderboard accounts.

  • aggregationField and additionalAggregationFields accept the documented post counter names, such as engagement, reach, videoViews, click, ctr, overperforming, or monetization. The API resolves each documented name to the stored counter internally; historical internal counter names are intentionally undocumented.

Queryparameters

VeldTypeBeschrijving
accountIds*stringComma-separated external account IDs, from the externalId of leaderboard rows.
aggregationField*stringDocumented post counter to aggregate per post type.
sizeintCount of accounts to return, between 1 and 200.Standaard: 20
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on post fields.
filtersOrstringOR filters on post fields.
excludesstringExclude results when a field contains a value.
existsstringComma-separated fields that must exist in matching posts.

Velden van het antwoord

VeldTypeBeschrijving
LeaderboardCategoryRow[]LeaderboardCategoryRow[]Per account post type breakdown. The response is a JSON array without a total wrapper.
->externalIdstringSocial network account/page ID.
->typesobjectBreakdown keyed by post type, each entry with value and docCount for the aggregated counter.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/posts/leaderboard/categories?accountIds=339028534278,224444370873&aggregationField=engagement&filters=publishedAt:-30%20days..now' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

12.Accounts

5 endpoints

Search and manage the social accounts tracked by Social Listening, such as media pages and competitors. These are listening entities, distinct from the connected social accounts used for publishing.

POST/accountsBearer vereist

12.2.Add an account

Add a social account to Social Listening. The account is fetched from the network, activated for listening, and returned. Requires a role with the listening manage permission.

Bodyparameters

VeldTypeBeschrijving
network*stringSocial network of the account: facebook, instagram, linkedin, etc.
accountIdstringExternal account ID or slug on the network. Provide accountId or slug.
slugstringAccount slug on the network. Provide accountId or slug.
instanceUrlstringInstance URL, required for federated networks such as Mastodon.

Velden van het antwoord

VeldTypeBeschrijving
AccountAccountCreated or updated account, with the same fields as search results.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/accounts' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "network": "facebook",
6 "slug": "mediapage"
7 }'
GET/accounts/categoriesBearer vereist

12.3.Get account categories

Return account category aggregations for autocomplete and listening filters.

  • The category filter and query field resolve to the localized account category internally; filter with category:<value> rather than a localized field path.
Limiet200 calls every 10 minutes per company and per endpoint, shared by all API tokens of the company. Each window opens with the first counted call. Creating or rotating a token neither resets nor extends the window; the 201st call in the window returns 429, and every later call returns 429 until the window closes. Each request counts as one call, whatever the number of items in a bulk request

Queryparameters

VeldTypeBeschrijving
sizeintCount of results to return.Standaard: 10
prefixstringCategory prefix.
selected*stringAlready selected categories, comma separated. Send an empty value when no category is selected yet.
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on account fields.
filtersOrstringOR filters on account fields.
excludesstringExclude results when a field contains a value.
existsstringComma-separated fields that must exist in each returned item.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of categories found.
rows.keystringCategory value.
rows.doc_countintNumber of accounts in the category.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/accounts/categories?prefix=News&selected=&filters=type:facebook&size=10' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/accounts/locationsBearer vereist

12.4.Search account locations

Return location accounts, such as city pages, matching a query. Local index results are combined with a remote network search. A type filter selecting the social network is required.

Queryparameters

VeldTypeBeschrijving
sizeintCount of results to return.Standaard: 20
qstringLocation search query.
filters*stringAND filters. The type:<network> filter selecting the social network to search is required.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of locations found.
rowsAccount[]Location accounts, including geoname data.
qstringEcho of the search query.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/accounts/locations?q=Paris&filters=type:facebook&size=20' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/accounts/statsBearer vereist

12.5.Get account stats

Return aggregated account counter statistics with optional trend and histogram data.

  • Accounts endpoints expose account counters only, currently follower_count (account fans or followers). The API resolves this documented name to the stored account counter internally, and responses echo the name the request used. Address it with the full counter path, for example sort=-counters.total.follower_count or filters=counters.graph.counter:follower_count. Post counters such as engagement or reach are invalid for Accounts.

Queryparameters

VeldTypeBeschrijving
filtersstringAND filters on account fields.
filtersOrstringOR filters on account fields.
excludesstringExclude results when a field contains a value.
existsstringComma-separated fields that must exist in each item.
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
metricstringAggregation metric: sum, avg, med, or percentiles.
dateTimeRangestringDate-time range used to calculate the trend.
timezonestringTimezone used to resolve previous periods for the trend.
percentilefloatQueried percentile when metric is percentiles.
granularitystringHistogram granularity: hour, day, week, month, or year. Auto-selected from the filtered period when omitted.

Velden van het antwoord

VeldTypeBeschrijving
totalobject[]Aggregated counter totals.
total.fieldstringAccount counter field.
total.valuefloatAggregated value.
total.trendfloatTrend versus the previous period when dateTimeRange is provided.
graphobject[]Counter histograms.
graph.counterstringAccount counter field.
graph.histogramobject[]Time-bucketed counter values.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/accounts/stats?filters=type:facebook;listeningActivated:true;counters.graph.counter:follower_count&metric=sum&granularity=day' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

13.Bots

6 endpoints

Manage automation bots that transform sources such as feeds, themes, or social accounts into publishable posts.

GET/bots/:botIdBearer vereist

13.2.Get a bot

Return one bot by UUID.

Queryparameters

VeldTypeBeschrijving
fieldsstringComma-separated fields to include.
embedstringCan embed running and spamControl.

Velden van het antwoord

VeldTypeBeschrijving
idstringBot UUID.
titlestringBot title.
brandIdintBrand attached to the bot.
activationobjectActivation and scheduling state.
sourceobjectSource configuration.
targetobject[]Target configurations.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/bots/5c9b6e52-8d4e-4f16-9f16-c01e9cbbd9e1?fields=id,title,brandId,activation,source,target&embed=running' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
POST/bots/bulkBearer vereist

13.3.Create bots in bulk

Create one or more bots. Source and target URNs must reference resources visible to the API token role.

  • Bot trigger counters and post-rate metrics use the documented post counters. Percentile-based triggers resolve the documented counter name before calculating the percentile.
  • The creator identity is server-managed. Bots created with a Bearer token use API <token name> as creatorName and have no creatorUserId. Client-supplied creator identity fields are ignored, so an API integration cannot impersonate a Nonli user.

Bodyparameters

VeldTypeBeschrijving
bot*Bot[]Bots to create.
->title*stringBot title.
->brandId*intBrand attached to the bot.
->autoboolIf false, created posts are kept for review before publishing.
->activationobjectActivation state and optional time window.
->timezonestringTimezone used for activation windows.
->runCyclePeriodobjectMinimum and maximum minutes between source reads.
->scheduleobjectPost scheduling options.
->source*objectSource object with a Nonli URN.
->target*object[]Target objects with Nonli URNs.
->postobject[]Post template configuration.
->fieldMappingobject[]Source-to-target field mappings.
->sourceMessagestringSource field used to build the post message.
->sourceTitlestringSource field used to build the post title.
->sourceImagestringSource field used to build the post image.
->trigger.counter[].fieldstringCounter field that must reach trigger.counter[].triggerValue before the bot posts. Accepts documented post counter names such as engagement or reach for social-account sources.
->trigger.counter[].triggerValueintCounter threshold used by the trigger.
->trigger.counter[].metricstringOptional aggregation metric used to calculate the trigger value, for example percentiles. The trigger counter field is resolved from the documented counter name before the aggregation is built.
->postRate.modestringPost type selection mode. Use manual for fixed post-type ratios, auto_all to auto-select from all post types, or auto_photo_link to auto-select between photo and link posts.
->postRate.metricstringPerformance metric used by automatic post type selection. Accepts documented post counter names such as engagement, reach, videoViews, and monetization.

Velden van het antwoord

VeldTypeBeschrijving
Bot[]Bot[]Created bots or per-item errors.
->idstringCreated bot UUID.
->creatorNamestringServer-managed creator. Bearer-created bots use API followed by the token name.
->creatorUserIdint|nullNull for bots created with an API token.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/bots/bulk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "bot": [
6 {
7 "title": "Morning feed review",
8 "brandId": 1,
9 "auto": false,
10 "activation": {
11 "alive": false
12 },
13 "timezone": "Europe/Paris",
14 "runCyclePeriod": {
15 "min": 30,
16 "max": 60
17 },
18 "source": {
19 "urn": "urn:nonli:feed:https://example.com/rss.xml",
20 "name": "Editorial feed"
21 },
22 "target": [
23 {
24 "urn": "urn:nonli:sa:facebook:PAGE_ID",
25 "name": "Facebook page"
26 }
27 ],
28 "post": [
29 {
30 "index": 0,
31 "prefix": "",
32 "suffix": ""
33 }
34 ],
35 "trigger": {
36 "counter": [
37 {
38 "field": "engagement",
39 "triggerValue": 75,
40 "metric": "percentiles"
41 }
42 ]
43 },
44 "postRate": {
45 "mode": "auto_all",
46 "metric": "engagement"
47 },
48 "fieldMapping": [
49 {
50 "source": "title",
51 "target": "message"
52 }
53 ],
54 "sourceMessage": "title",
55 "sourceTitle": "title",
56 "sourceImage": "og_image"
57 }
58 ]
59 }'

Voorbeeld van een antwoord

json
1[
2 {
3 "id": "5c9b6e52-8d4e-4f16-9f16-c01e9cbbd9e1",
4 "title": "Morning feed review",
5 "brandId": 1,
6 "creatorName": "API Website publisher",
7 "creatorUserId": null,
8 "activation": {
9 "alive": false
10 }
11 },
12 {
13 "error": "Bot creation failed"
14 }
15]
PUT/bots/bulkBearer vereist

13.4.Update bots in bulk

Update one or more bots. Each item must include the bot UUID and only the fields to change.

  • Bot trigger counters and post-rate metrics use the documented post counters. Percentile-based triggers resolve the documented counter name before calculating the percentile.

Bodyparameters

VeldTypeBeschrijving
bot*Bot[]Bots to update.
->id*stringBot UUID.
->titlestringBot title.
->brandIdintBrand attached to the bot.
->autoboolWhether the bot publishes automatically.
->activationobjectActivation state and optional time window.
->runCyclePeriodobjectMinimum and maximum minutes between source reads.
->scheduleobjectPost scheduling options.
->sourceobjectSource object with a Nonli URN.
->targetobject[]Target objects with Nonli URNs.
->postobject[]Post template configuration.
->fieldMappingobject[]Source-to-target field mappings.
->trigger.counter[].fieldstringCounter field that must reach trigger.counter[].triggerValue before the bot posts. Accepts documented post counter names such as engagement or reach for social-account sources.
->trigger.counter[].triggerValueintCounter threshold used by the trigger.
->trigger.counter[].metricstringOptional aggregation metric used to calculate the trigger value, for example percentiles. The trigger counter field is resolved from the documented counter name before the aggregation is built.
->postRate.modestringPost type selection mode. Use manual for fixed post-type ratios, auto_all to auto-select from all post types, or auto_photo_link to auto-select between photo and link posts.
->postRate.metricstringPerformance metric used by automatic post type selection. Accepts documented post counter names such as engagement, reach, videoViews, and monetization.

Voorbeeld

bash
1curl --location --request PUT 'https://api.nonli.com/v2.1/bots/bulk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "bot": [
6 {
7 "id": "5c9b6e52-8d4e-4f16-9f16-c01e9cbbd9e1",
8 "title": "Morning feed review",
9 "activation": {
10 "alive": true
11 },
12 "runCyclePeriod": {
13 "min": 45,
14 "max": 90
15 }
16 }
17 ]
18 }'

Voorbeeld van een antwoord

json
1[
2 {
3 "id": "5c9b6e52-8d4e-4f16-9f16-c01e9cbbd9e1",
4 "title": "Morning feed review",
5 "brandId": 1,
6 "activation": {
7 "alive": true
8 }
9 },
10 {
11 "error": "Bot update failed"
12 }
13]
DELETE/bots/:botIdBearer vereist

13.5.Delete a bot

Delete one bot by UUID. A successful deletion returns HTTP 204 with no response body.

Voorbeeld

bash
1curl --location --request DELETE 'https://api.nonli.com/v2.1/bots/5c9b6e52-8d4e-4f16-9f16-c01e9cbbd9e1' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'
GET/bots/infoBearer vereist

13.6.Get bot configuration info

Return schedule periods, target validation rules, and bot configuration constraints used to build valid bot payloads.

Queryparameters

VeldTypeBeschrijving
sourceUrnstringOptional source URN to evaluate source-specific configuration.
targetUrnstringOptional target URN to evaluate target-specific configuration.

Velden van het antwoord

VeldTypeBeschrijving
schedulePeriodsobjectAvailable schedule period identifiers and labels.
targetValidationConfigsobjectValidation rules by target type.
configobjectBot defaults and constraints, including AI generated text and consultation frequency.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/bots/info?sourceUrn=urn%3Anonli%3Afeed%3Ahttps%3A%2F%2Fexample.com%2Frss.xml&targetUrn=urn%3Anonli%3Asa%3Afacebook%3APAGE_ID' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

14.Media

2 endpoints

Search reusable media and metadata used by the publishing composer.

GET/media/tagsBearer vereist

14.2.Get media tags

Return media tags for autocomplete and asset filtering.

Queryparameters

VeldTypeBeschrijving
sizeintMaximum number of results to return.Standaard: 20 or endpoint-specific
qstringFull-text search query.
qfstringComma-separated fields used by the full-text query.
filtersstringAND filters on item fields. Use semicolons between filters and ".." for ranges. Send the separators ":", ";", "," and ".." as raw characters, which every search endpoint accepts, and percent-encode only characters inside values, such as spaces (%20). Encoded separators behave differently by endpoint: GET /listening/social, GET /posts/leaderboard, and GET /accounts read the raw query string and treat them as literal value characters, so the filter matches nothing or returns 400, while the other GET search endpoints, such as GET /posts, decode the query string first and treat them as separators. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
filtersOrstringOR filters on item fields. Example: "status:200,203". On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
excludesstringExclude results when a field contains a value. On post-backed counter filters, documented counter names are resolved for counters.total.field, counters.graph.counter, counters.histogram.field, and counters.period.field.
existsstringComma-separated fields that must exist in each returned item. Fields must belong to the endpoint entity; invalid fields return 400 Bad Request.

Velden van het antwoord

VeldTypeBeschrijving
totalintTotal number of tags found.
rows.keystringTag value.
rows.doc_countintNumber of media items using the tag.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/media/tags?size=100' \
2 --header 'Authorization: Bearer YOUR_API_TOKEN'

15.Uploads

6 endpoints

Upload images, videos, and documents before attaching them to posts.

To upload a video:

  1. 1Compute the SHA-256 of the file.
  2. 2Request a token from POST /upload/video/token with sha256. If the response contains video, reuse that video and stop.
  3. 3Otherwise upload the chunks to POST /upload/video/chunk with the returned token and chunkSize, and reuse the URL of the final response. If the last chunk request fails or returns 409, wait a few seconds and re-send it until its response contains the video.
POST/upload/imageBearer vereist

15.1.Upload an image

Upload a base64 image and receive the Fontan slug used by posts and shortlinks.

Bodyparameters

VeldTypeBeschrijving
b64Image*stringBase64 encoded image.
keepFormatboolKeep the original format when possible.
faceDetectboolRun face detection/cropping assistance.Standaard: true

Velden van het antwoord

VeldTypeBeschrijving
slugstringFontan image slug.
urlstringImage URL when available.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/image' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "b64Image": "data:image/png;base64,iVBORw0KGgo...",
6 "keepFormat": true
7 }'
POST/upload/video/tokenBearer vereist

15.2.Create upload video token

Open a chunked video upload session, or reuse a video the company already stores when you send the SHA-256 of the file. The session response includes chunkSize, which defines the maximum chunk size to send.

  • When sha256 matches content the company already stores, the response is {"video": {...}} with that video and no upload is needed. Otherwise the session response (token, size, chunkSize, chunkIndex) is returned. The declared hash is only a lookup key: an upload is always stored under the SHA-256 the API computes from the received bytes. An invalid sha256 returns 400 Bad Request.
  • Each request opens a new upload session; a Bearer API token never resumes a previous one.
  • The API tokens of a company can hold at most 20 open video upload sessions; the next token request returns 429 Too Many Requests. A session that receives no chunk for 30 minutes stops counting.

Bodyparameters

VeldTypeBeschrijving
name*stringFile name.
type*stringVideo MIME type.
size*intFile size in bytes.
sha256stringLower or upper case hexadecimal SHA-256 of the complete file. Reuses the video the company already stores for that content instead of uploading it again.
durationintVideo duration in seconds.
widthintVideo width in pixels.
heightintVideo height in pixels.
titlestringVideo title.
descriptionstringVideo description.
customTagstring[]Video custom tags.

Velden van het antwoord

VeldTypeBeschrijving
videoobjectVideo the company already stores for the sent sha256. When present, no upload session is opened and no other field is returned.
tokenstringUpload token.
sizeintFile size in bytes.
chunkSizeintChunk size in bytes.
chunkIndexintNext chunk index.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/video/token' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "sha256": "3a5f1c0e9b7d4f2a6c8e1b3d5f7a9c0e2b4d6f8a1c3e5b7d9f0a2c4e6b8d1f3a",
6 "name": "35427-407130886_small.mp4",
7 "size": 1338788,
8 "type": "video/mp4",
9 "title": "My video title",
10 "description": "My video description",
11 "customTag": ["foo", "bar"]
12 }'

Voorbeeld van een antwoord

json
1{
2 "video": {
3 "id": "8f14e45fceea167a5a36dedd4bea2543",
4 "url": "https://cdn.example.com/videos/35427-407130886_small.mp4",
5 "title": "My video title",
6 "type": "video/mp4",
7 "size": 1338788
8 }
9}
POST/upload/video/existsBearer vereistVerouderd

15.3.Check uploaded video existence (legacy)

Legacy compatibility lookup of a video uploaded before the server-owned upload flow with the same client md5sum. New integrations must not use it.

  • This lookup never finds a video uploaded since the server-owned upload flow, which stores every upload under the SHA-256 the API computes. To avoid uploading a video again, send its sha256 to POST /upload/video/token instead.

Bodyparameters

VeldTypeBeschrijving
md5sum*stringLegacy client video ID, md5 encoded.
namestringIgnored. The video is found whatever its file name.

Velden van het antwoord

VeldTypeBeschrijving
urlstring|nullThe response is {"url": null} when no video is found. Otherwise it is the found video object, whose url is the video URL and id its ID.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/video/exists' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "md5sum": "64bed820ce612754d1e3e957edfc69c7"
6 }'

Voorbeeld van een antwoord

json
1{
2 "url": null
3}
POST/upload/video/chunkBearer vereist

15.4.Upload video chunk

Upload one base64 chunk for a video upload session. The response is {size} until the upload is complete, then the final video.

  • The final video is the company's canonical video for that content: the same bytes always return the same URL and are stored and counted once, whatever the file name, extension, or API token. Reuse this URL for every publication destination.
  • Large files can take longer to finalize. If the last chunk request fails with a network error, a timeout, 502, 504, or 409 Conflict (the upload is still being finalized), wait a few seconds and re-send the same last chunk, with the same token and chunk number, until the response contains the video. Re-sending it returns the same video and never stores the content twice. 404 Not Found means the upload session expired: restart the upload with a new token.

Bodyparameters

VeldTypeBeschrijving
token*stringUpload token.
chunk*intChunk number.
data*stringChunk bytes as base64.

Velden van het antwoord

VeldTypeBeschrijving
sizeintUploaded size after this chunk, returned until the upload is complete.
idstringVideo ID, returned when the last chunk has been uploaded.
urlstringCanonical video URL, returned when the last chunk has been uploaded.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/video/chunk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "token": "e5bab8115967331ce0db284e03622cf0",
6 "chunk": 1,
7 "data": "AAAAIGZ0eXBtcDQyAAAAAG1wNDJtcDQxaXNvbWF2YzEAABF9b..."
8 }'
POST/upload/document/tokenBearer vereist

15.5.Create upload document token

Create or resume a document upload session. The response includes chunkSize for chunked upload.

Bodyparameters

VeldTypeBeschrijving
name*stringFile name.
type*stringDocument MIME type, commonly application/pdf.
size*intFile size in bytes.
md5sum*stringUnique document ID, md5 encoded.
titlestringDocument title.
descriptionstringDocument description.
pageCountintNumber of pages in the document.

Velden van het antwoord

VeldTypeBeschrijving
tokenstringUpload token.
sizeintFile size in bytes.
chunkSizeintChunk size in bytes.
chunkIndexintNext chunk index.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/document/token' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "md5sum": "64bed820ce612754d1e3e957edfc69c7",
6 "name": "press-release.pdf",
7 "size": 1024000,
8 "type": "application/pdf",
9 "title": "Press release",
10 "pageCount": 3
11 }'
POST/upload/document/chunkBearer vereist

15.6.Upload document chunk

Upload one base64 chunk for a document upload session. The final response includes the document id and URL.

Bodyparameters

VeldTypeBeschrijving
token*stringUpload token.
chunk*intChunk number.
data*stringChunk bytes as base64.

Velden van het antwoord

VeldTypeBeschrijving
sizeintUploaded size after this chunk.
idstringDocument ID, returned when the last chunk has been uploaded.
urlstringDocument URL, returned when the last chunk has been uploaded.

Voorbeeld

bash
1curl --location 'https://api.nonli.com/v2.1/upload/document/chunk' \
2 --header 'Content-Type: application/json' \
3 --header 'Authorization: Bearer YOUR_API_TOKEN' \
4 --data '{
5 "token": "e5bab8115967331ce0db284e03622cf0",
6 "chunk": 1,
7 "data": "JVBERi0xLjQKJc..."
8 }'