Bring Your Own Content (BYOC) Overview
The Meltwater platform ingests and enriches data from a wide variety of sources, including news and social platforms. With Bring Your Own Content (BYOC), you can also ingest your own first-party content into the platform.
BYOC content is visible only to your company. Once ingested, it is stored in the same data schema as other Meltwater data and enriched with the same metadata (such as sentiment, language, and key phrases). This makes your content searchable and analyzable alongside Meltwater’s global media coverage.
The API enables you to upload this content in JSON format, using a schema defined by Meltwater. Once uploaded, the content is indexed and available in the Meltwater application and API for analysis, dashboards, and reporting.
Because BYOC is a push API, ingestion is controlled by you. You decide what to send and when, whether in real-time, scheduled batches, or ad hoc uploads.
In this tutorial we’ll explain how to “bring your own content” to the Meltwater platform. You can use this feature to add content of your choosing which is visible only to your company.
Before you start
To run through this tutorial, you will need:
- Your Meltwater API token
- Access to the Bring Your Own Content feature, which can be requested from Meltwater Support.
Authentication
You need to provide your API token when you call any Meltwater API endpoint.
You provide the API token as a header called apikey, for example:
curl -X POST \
--url "https://api.meltwater.com/v3/imports/documents" \
--header "Accept: application/json" \
--header "apikey: **********"
--data @documents.jsonFor full details take a look at the Authentication page.
API details to import documents
You can import documents by sending a POST request to the /imports/documents endpoint.
Query Parameters:
import_tag(optional): Comma-separated list of string tags to label or group the batch of documents. This can help with tracking and filtering later using monitoring endpoints.company_id(optional): Meltwater company id if running a request on behalf of another company
Example document import format
{
"documents": [
{
"id": "12345",
"url": "http://example.com",
"timestamp": 1748272125000,
"content": {
"title": "Example Title",
"subtitle": "Example Subtitle",
"text": "Example text content",
"duration": 120
},
"originPlatform": "youtube",
"contentType": "video",
"attachments": [
{
"name": "Attachment Name",
"url": "http://example.com",
"mime": "image/png",
"altText": "Alt text for the attachment",
"type": "image",
"thumbnail": "http://example.com"
}
],
"source": {
"name": "The Meltwater Times",
"url": "http://example.com",
"location": {
"countryCode": "DE",
"locationString": "Berlin, Germany",
"coordinates": {
"lat": 52.52,
"lon": 13.405
}
}
},
"user": {
"name": "John Doe",
"url": "http://example.com",
"gender": "m",
"location": {
"countryCode": "DE",
"locationString": "Berlin, Germany",
"coordinates": {
"lat": 52.52,
"lon": 13.405
}
}
},
"parent": {
"url": "http://example.com",
"title": "Parent Document Title"
},
"metrics": {
"views": 100,
"audience": 50,
"ave": 4.5,
"score": 3.2,
"likes": 50,
"shares": 50,
"comments": 50,
"replies": 50
},
"sentiment": "positive"
}
]
}Document fields
| Field | Required | Notes |
|---|---|---|
| id | Optional | An id that you would like to use to identify the document during future requests (e.g. updates/deletes). If provided, the value must be unique within the batch. |
| url | Required | Article / post url |
| timestamp | Required | Epoch (in milliseconds) |
| content | Optional | |
| content.title | Optional | Title of the document |
| content.subtitle | Optional | Subtitle / ingress |
| content.text | Optional | Full text of the article / post |
| content.duration | Optional | Relevant for video/audio content (in seconds) |
| originPlatform | Required | [1] |
| contentType | Required | [2] |
| attachments | Optional | Items are objects with required subfields. Use for attaching additional media objects, like: images, videos, etc. |
| attachments[].name | Optional | Arbitrary name of the attachment |
| attachments[].url | Required | Url of the attachment |
| attachments[].mime | Required | Mime type |
| attachments[].altText | Optional | Alternative text / description. Usually for image / video attachments |
| attachments[].type | Required | [3] |
| attachments[].thumbnail | Optional | Thumbnail URL of the attachment, i.e. image thumbnail for video attachment |
| source | Required | |
| source.name | Required | Source name. If not applicable set it empty |
| source.url | Required | Url of the source, channel, etc. |
| source.location | Optional | |
| source.location.countryCode | Optional | ISO 3166-1 alpha-2 country code |
| source.location.locationString | Optional | Free text description of the location |
| source.location.coordinates | Optional | Contains required fields lat and lon |
| source.location.coordinates.lat | Required (if parent exists) | Geo latitude (numeric, decimal) |
| source.location.coordinates.lon | Required (if parent exists) | Geo longitude (numeric, decimal) |
| user | Optional | User / author / presenter / speaker. Name or handle must be present |
| user.name | Required if handle not supplied | User / author / presenter / speaker full name |
| user.handle | Required if name not supplied | Intended mainly for social |
| user.url | Optional | User / author / presenter / speaker profile url |
| user.gender | Optional | [4] |
| user.location | Optional | |
| user.location.countryCode | Optional | ISO 3166-1 alpha-2 country code |
| user.location.locationString | Optional | Free text description of the location |
| user.location.coordinates | Optional | Contains required fields lat and lon |
| user.location.coordinates.lat | Required (if parent exists) | Geo latitude (numeric, decimal) |
| user.location.coordinates.lon | Required (if parent exists) | Geo longitude (numeric, decimal) |
| parent | Optional | Parent entity of this document - parent post, etc. |
| parent.url | Optional | Url of the parent post |
| parent.title | Optional | Title of the parent post |
| product | Optional | Mainly for product reviews |
| product.name | Optional | Product name |
| metrics | Optional | |
| metrics.views | Optional | View / impression count |
| metrics.audience | Optional | Audience / reach for given source |
| metrics.ave | Optional | Advertising Value Equivalency |
| metrics.score | Optional | Mainly for product reviews and voice of customers. Review score. |
| metrics.likes | Optional | Likes count |
| metrics.shares | Optional | Shares count |
| metrics.comments | Optional | Comments count |
| metrics.replies | Optional | Replies count |
| sentiment | Optional | Sentiment of the document [5] |
| customFields | Optional | Explore+ custom fields [6] |
Notes on fields
[1] originPlatform possible values:
youtube, podcasts, facebook, instagram, reddit, sina_weibo, wechat, twitter, linkedin, pinterest, twitch, tiktok, douyin, little_red_book, youku, bilibili, threads, kakaotalk, linevoom, discord, snapchat, bluesky, news_publisher, broadcast, tender_portal, reviews, blogs, forums, social_comments
[2] contentType possible values:
video, comment, repost, reply, quoted, audio, post, online_press, print_press, tender, product_review, voc
Note: Values must match platform-specific rules.
[3] attachments[].type possible values:
image, audio, video
[4] user.gender possible values:
m (male), f (female), n (other)
[5] sentiment possible values:
neutral, positive, negative, unknown
[6] For using Explore+ custom fields, see the Explore+ Custom Fields guide.
JSON schema
A schema for validating individual documents is available here: BYOC JSON schema
Sending the documents
Suppose that you save a set of documents as defined above into a file named documents.json.
Then to upload that file with curl you can execute:
curl -X POST \
--url "https://api.meltwater.com/v3/imports/documents" \
--header "Accept: application/json" \
--header "apikey: **********"
--data @documents.jsonYou can also submit documents on behalf of another Meltwater company you’re authorized for. For more information on working with multiple Meltwater companies, see the following guide.
API Limitations
- Maximum 500 documents per request
- Maximum 25MB payload size per request
- General API call limits
Verification
If all goes well, you will receive a response providing a batch ID and a count of the uploaded documents, e.g.:
{
"batchId": "3ccd4b7f-5987-45ca-a774-7be330763489",
"count": 20
}It is possible to track the progress of your batch using Monitoring APIs. Alternatively, you can also check your documents in our app.
To find all documents that you have imported via this API, you can query like this:
metaData.provider.type:"byod"
To find the documents using the supplied batchId from the response, you can query like this:
metaData.applicationTags:"byod:batchId={batchId}"
If you supplied your own id field on the documents, you can find them individually like this:
externalId:{id}
Here is an example of how it might look in the Explore advanced search:
We recommend to include an id field with every document, as in general it makes it easier to reliably find it later on.
Otherwise you may need to search on some other known pieces of information from the documents (e.g. title).
Frequently Asked Questions
For answers to common questions, see the BYOC FAQ.