Content API V2

Health Check

The health-check will show return status 200 with text body:

URL: /content/health-check

Method: GET

Example Response:

This is Content API V2!

Service Description

The service-description will show following information for an API:

  • Gives the Python Version the API using

  • Gives the list of all installed Python packages

  • Gives the name of API

  • Gives all the available versions

  • Gives a list of middleware being used

  • Gives all available routes for each versions.

URL: /content/service-description

Method: GET

Example Response:

{
  "user_id": "not-set",
  "request_from": "not-set",
  "request_id": "not-set",
  "trace_id": "not-set",
  "data": {
    "python_version": "3.9.5",
    "installed_packages": [
      "wheel==0.37.1",
      "zipp==3.8.0"
    ],
    "name": "content",
    "versions": [
      "v1"
    ],
    "middleware": [
      "FalconHealthCheckMiddleware",
      "FalconResponseGeneratorMiddleware"
    ],
    "routes": {
      "v1": {
        "content": [
          "get",
          "post",
          "post_filter",
          "put"
        ],
        "content/{content_gid:int}": [
          "get",
          "post",
          "post_filter",
          "put"
        ],
        "filter": [
          "get",
          "post",
          "post_filter",
          "put"
        ]
      }
    }
  }
}

Content Resource

Class : v1.resources.content.content.ContentResource

Note

Allowed Methods:

  • GET

  • POST

  • PUT

GET Method

Request

Response:

The response will depend on the content type. The following example is the response for an article.

[
    {
        "gid": "8-1",
        "created_on": 1660639020,
        "created_by": 123,
        "title": "Article title",
        "snippet": "Article snippet",
        "content": "Article content",
        "sources": [
            {
                "external_source_id": 467,
                "name": "USA Today",
                "article_url": "https://www.usatoday.com/story/news/world/2022/08/15/james-webb-telescope-name-planet/10324529002/",
                "published_on": 1660536000,
                "extraction_method": "newspaper",
                "ingested_on": 1660592220,
                "article_url_domain": "usatoday.com"
            }
        ],
        "is_rane_proprietary": false,
        "language": "en",
        "article_published_on": 1660708740,
        "publications": [
            {
              "location": "crawl",
              "publisher_id": 0,
              "published_on": 1660592259
            }
        ],
        "tags_country": [],
        "tags_industry": [],
        "tags_region": [],
        "tags_risk": [],
        "tags_products_and_services": [],
        "tags_key_terms": [],
        "article_tags": [],
        "article_id": 21471948,
        "article_version": 1,
        "updated_on": 1660592259,
        "updated_by": 0,
        "type": 33,
        "tags": [
            "13-277",
            "13-8"
        ],
        "source_ids": [
            467
        ],
        "legacy_gid": "008001021471948",
        "origin_id": "8-1",
        "parent_id": "8-1",
        "brief_ids": [],
        "mongo_id": "62faa0b50e2adda640fe9d15"
    }
]

GET Articles Method

Request

{
    "gids" : ["8-1", "8-2"]
}

Response:

The response will depend on the content type. The following example is the response for an article.

[
    {
        "gid": "8-1",
        "legacy_gid": "008001022308952",
        "type_slug": "add_story",
        "title": "Power Cuts Drive South African Factory Activity to 14-Month Low",
        "snippet": "Business activity in South Africa’s manufacturing industry fell to a 14-month low in September as electricity-supply constraints in the continent’s most industrialized economy disrupted operations. A gauge tracking business activity declined to 38.5 from 50.6 in August, Absa Group Ltd. said on Monday. That’s the lowest monthly reading since July 2021, when deadly riots, looting and arson disrupted supply chains, industrial output and demand for manufactured goods. An outcome below 50 signals contraction.",
        "content": "Business activity in South Africa’s manufacturing industry fell to a 14-month low in September as electricity-supply constraints in the continent’s most industrialized economy disrupted operations. A gauge tracking business activity declined to 38.5 from 50.6 in August, Absa Group Ltd. said on Monday. That’s the lowest monthly reading since July 2021, when deadly riots, looting and arson disrupted supply chains, industrial output and demand for manufactured goods. An outcome below 50 signals contraction.",
        "sources": [
            {
                "external_source_id": 727,
                "article_url": "https://www.bloomberg.com/news/articles/2022-10-03/power-cuts-drive-south-african-factory-activity-to-14-month-low",
                "name": "Bloomberg",
                "extraction_method": "extracted",
                "ingested_on": 1664795843,
                "article_url_domain": "bloomberg.com"
            }
        ],
        "source_ids": [
            727
        ],
        "language": "en",
        "publications": [],
        "tags": [],
        "sync_isodate": "2022-10-03T11:21",
        "origin_id": "8-478887",
        "parent_id": "8-478887",
        "created_by": "0",
        "created_on": 1664796112,
        "published_on": 1664796112,
        "updated_by": "0",
        "updated_on": 1664796112,
        "id": "633ac5d06d8ce958498afe4c"
    },
    {
        "gid": "8-2",
        "legacy_gid": "008001022308947",
        "type_slug": "add_story",
        "title": "South Africa: Stage 3 Load-Shedding to Continue Until 6 October",
        "snippet": "Stage 3 load-shedding will continue until 5 a.m. on 6 October, Eskom said on Sunday. The power utility said the continued load-shedding is necessary due to its shortage of generation capacity as a result of persistent high levels of breakdowns.",
        "content": "Stage 3 load-shedding will continue until 5am on Thursday, Eskom said on Sunday.\n\nThe power utility said the continued load-shedding is necessary due to its shortage of generation capacity as a result of persistent high levels of breakdowns.\n\n“After the shutdown of Camden power station due to the demineralised water contamination last week, the first of seven generating units returned to service on Saturday evening. The remaining units are anticipated to return to service over the next eight days, while one will remain on planned maintenance. A generating unit each at Kusile and Majuba power stations were returned to service,” Eskom said.\n\nA generating unit each at Duvha, Kendal, Komati, Kusile, Matimba, Lethabo and Tutuka power stations were taken offline for repairs.\n\n“Furthermore, the delay of two generating units at Kendal power station and one generating unit at Tutuka power station have added to the capacity constraint. Emergency generation facilities have been adequately replenished. We now have 6,893MW on planned maintenance, while another 16,168MW of capacity is unavailable due to breakdowns,” the power utility said.\n\nA further update will be given on Wednesday afternoon or when there are  significant changes.",
        "sources": [
        {
          "external_source_id": 1849,
          "article_url": "https://www.businesslive.co.za/bd/national/2022-10-02-stage-3-load-shedding-to-continue-until-thursday/",
          "name": "Business Day",
          "extraction_method": "extracted",
          "ingested_on": 1664795584,
          "article_url_domain": "businesslive.co.za"
        }
        ],
        "source_ids": [
        1849
        ],
        "language": "en",
        "publications": [],
        "tags": [
        "001000000000004"
        ],
        "sync_isodate": "2022-10-03T11:16",
        "origin_id": "8-478885",
        "parent_id": "8-478885",
        "created_by": "0",
        "created_on": 1664795812,
        "published_on": 1664795812,
        "updated_by": "0",
        "updated_on": 1664795812,
        "id": "633ac4a4eaa64415318aeebe"
    }
]

POST Method

Request

{
    "created_on": 1660639020,
    "created_by": 123,
    "title": "Article title",
    "snippet": "Article snippet",
    "content": "Article content",
    "sources": [
        {
            "external_source_id": 467,
            "name": "USA Today",
            "article_url": "https://www.usatoday.com/story/news/world/2022/08/15/james-webb-telescope-name-planet/10324529002/",
            "published_on": 1660536000,
            "extraction_method": "newspaper",
            "ingested_on": 1660592220,
            "article_url_domain": "usatoday.com"
        }
    ],
    "is_rane_proprietary": false,
    "language": "en",
    "article_published_on": 1660708740,
    "publications": [
        {
          "location": "crawl",
          "publisher_id": 0,
          "published_on": 1660592259
        }
    ],
    "tags_country": [],
    "tags_industry": [],
    "tags_region": [],
    "tags_risk": [],
    "tags_products_and_services": [],
    "tags_key_terms": [],
    "article_tags": [],
    "article_id": 21471948,
    "article_version": 1,
    "updated_on": 1660592259,
    "updated_by": 0,
    "type": 33,
    "tags": [
        "13-277",
        "13-8"
    ],
    "source_ids": [
        467
    ],
    "legacy_gid": "008001021471948",
    "origin_id": "8-9-0",
    "parent_id": "8-15-0"
    "brief_ids": []
}

Response:

[
    {
        "gid": "8-16",
        "created_on": 1660639020,
        "created_by": 123,
        "title": "Article title",
        "snippet": "Article snippet",
        "content": "Article content",
        "sources": [
            {
                "external_source_id": 467,
                "name": "USA Today",
                "article_url": "https://www.usatoday.com/story/news/world/2022/08/15/james-webb-telescope-name-planet/10324529002/",
                "published_on": 1660536000,
                "extraction_method": "newspaper",
                "ingested_on": 1660592220,
                "article_url_domain": "usatoday.com"
            }
        ],
        "is_rane_proprietary": false,
        "language": "en",
        "article_published_on": 1660708740,
        "publications": [
            {
              "location": "crawl",
              "publisher_id": 0,
              "published_on": 1660592259
            }
        ],
        "tags_country": [],
        "tags_industry": [],
        "tags_region": [],
        "tags_risk": [],
        "tags_products_and_services": [],
        "tags_key_terms": [],
        "article_tags": [],
        "article_id": 21471948,
        "article_version": 1,
        "updated_on": 1660592259,
        "updated_by": 0,
        "type": 33,
        "tags": [
            "13-277",
            "13-8"
        ],
        "source_ids": [
            467
        ],
        "legacy_gid": "008001021471948",
        "origin_id": "8-9-0",
        "parent_id": "8-15-0",
        "brief_ids": [],
        "mongo_id": "62faa0b50e2adda640fe9d15"
    }
]

POST Update Method

Request

  • Method: POST

  • URL: https://rane-api-dev.ranenetwork.com/content/v1/content/update

  • Endpoint meant to update array fields in MongoDB

  • Payload fields:
    • gids: gids of the articles to update

    • <FIELD>: fields to update and value associated. The value can be a single object or a list of objects

  • Supports adding new entry to the following array fields:
    • publications

  • Request Object:

{
    "gids": ["8-1", "8-2"]
    "publications": [
        {
            "location": "monitoring",
            "published_id": 1,
            "published_on": 123456789,
            "brief_id": "8-0"
        },
        {
            "location": "monitoring",
            "published_id": 2,
            "published_on": 123456788,
            "brief_id": "8-3"
        },
    ]
}

Response Object:

Note

Computed fields:
  • publications: computed in a lambda to add a new entry whenever a brief is published

The entire objects are returned but in the following only a few fields are shown as an example

[
    {
        "gid": "8-1",
        "created_on": 1660639020,
        "created_by": 123,
        "title": "First article",
        "publications": [
            {
              "location": "crawl",
              "publisher_id": 0,
              "published_on": 1660592259
            },
            {
                "location": "monitoring",
                "published_id": 1,
                "published_on": 123456789,
                "brief_id": "8-0"
            },
            {
                "location": "monitoring",
                "published_id": 2,
                "published_on": 123456788,
                "brief_id": "8-3"
            }
        ]
    },
    {
        "gid": "8-2",
        "created_on": 1660639020,
        "created_by": 321,
        "title": "Second article",
        "publications": [
            {
              "location": "external",
              "publisher_id": 0,
              "published_on": 1660592259
            },
            {
                "location": "monitoring",
                "published_id": 1,
                "published_on": 123456789,
                "brief_id": "8-0"
            },
            {
                "location": "monitoring",
                "published_id": 2,
                "published_on": 123456788,
                "brief_id": "8-3"
            }
        ]
    }
]

PUT Method

Request

{
    "title": "A new Title",
    "snippet": "A new Snippet"
}

Response Object:

{
    "gid": "8-1",
    "created_on": 1660639020,
    "created_by": 123,
    "title": "A new Title",
    "snippet": "A new Snippet",
    "content": "Article content",
    "sources": [
        {
            "external_source_id": 467,
            "name": "USA Today",
            "article_url": "https://www.usatoday.com/story/news/world/2022/08/15/james-webb-telescope-name-planet/10324529002/",
            "published_on": 1660536000,
            "extraction_method": "newspaper",
            "ingested_on": 1660592220,
            "article_url_domain": "usatoday.com"
        }
    ],
    "is_rane_proprietary": false,
    "language": "en",
    "article_published_on": 1660708740,
    "publications": [
        {
          "location": "crawl",
          "publisher_id": 0,
          "published_on": 1660592259
        }
    ],
    "tags_country": [],
    "tags_industry": [],
    "tags_region": [],
    "tags_risk": [],
    "tags_products_and_services": [],
    "tags_key_terms": [],
    "article_tags": [],
    "article_id": 21471948,
    "article_version": 1,
    "updated_on": 1660592259,
    "updated_by": 0,
    "type": 33,
    "tags": [
        "13-277",
        "13-8"
    ],
    "source_ids": [
        467
    ],
    "legacy_gid": "008001021471948",
    "origin_id": "8-1",
    "parent_id": "8-1",
    "brief_ids": [],
    "mongo_id": "62faa0b50e2adda640fe9d15"
}

Content Filter Resource

Class : v1.resources.content.filter.ContentFilterResource

Note

Allowed Methods:

  • POST

POST Method

Request

{
    "payload_template": "monitoring",
    "page": 1,
    "size": 24,
    "gids": ["8-19-1", "8-22-1"],
    "parent_id": "8-15-1",
    "origin_id": "8-1-1",
    "types": [33],
    "keyword_search": "USA 5g",
    "source_search": "bloomberg",
    "source_ids": [727, 48],
    "tags": ["13-4", "13-6"],
    "ingested_on": {
        "from": 1659081000,
        "to": 1659081097
    },
    "published_on": {
        "from": 1659081000,
        "to": 1659081097
    },
    "type_slugs": ["advisory", "explainer", "insights"],
    "status": ["draft", "published"]
}

Response Object:

The response will be a list of the results matching the filters

Brief Definition Resource

Class : v1.resources.brief.brief_definition.BriefDefinitionResource

Note

Allowed Methods:

  • GET

  • POST

  • PUT

GET Method

Request

Response Object:

[
    {
        "name": "Brief 1",
        "display_name": "Brief 1 Display Name",
        "status": "active",
        "send_type": [
            "html"
        ],
        "category": [
            {
                "gid": "123-321",
                "display_name": "Cat 1 display name",
                "status": "active",
                "subcategory": [
                    {
                        "gid": "999-000",
                        "display_name": "SubCat 1 display name",
                        "status": "active"
                    },
                    {
                        "gid": "000-999",
                        "display_name": "SubCat 2 display name",
                        "status": "inactive"
                    }
                ]
            },
            {
                "gid": "321-123",
                "display_name": "Cat 2 display name",
                "status": "inactive"
            }
        ],
        "publication_detail": {
            "frequency": "weekly",
            "time": 123456789,
            "recurrence": {
                "days": [
                    2
                ],
                "start_date": 123456789
            }
        },
        "template_option": {
            "first_title": "First Title",
            "second_title": "Second Title",
            "tagline": {
                "show": true,
                "text": "Some tagline"
            },
            "top_logo": {
                "src": "s3://some/bucket/logo.png",
                "height": 40
            },
            "table_of_content": {
                "show": false,
                "text": "No TOC text"
            },
            "theme_color": "#123456",
            "show_icon": [
                "email",
                "feedback"
            ],
            "show_source": true,
            "show_curated_by_rane": true,
            "show_subscribe_unsubscribe": false,
            "show_manage_preference": false,
            "empty_category": {
                "show": true,
                "text": "Empty category text"
            },
            "empty_subcategory": {
                "show": false,
                "text": "Nothing to show for empty subcategories"
            },
            "footer_note": {
                "show": true,
                "text": "Footer notes"
            }
        },
        "internal_notes": "Some Internal Notes",
        "id": "62ebc76f3b2ac2bfee30fe0e"
    }
]

POST Method

Request

{
    "name": "Brief 1",
    "display_name": "Brief 1 Display Name",
    "status": "active",
    "send_type": [
        "html"
    ],
    "category": [
        {
            "gid": "123-321",
            "display_name": "Cat 1 display name",
            "status": "active",
            "subcategory": [
                {
                    "gid": "999-000",
                    "display_name": "SubCat 1 display name",
                    "status": "active"
                },
                {
                    "gid": "000-999",
                    "display_name": "SubCat 2 display name",
                    "status": "inactive"
                }
            ]
        },
        {
            "gid": "321-123",
            "display_name": "Cat 2 display name",
            "status": "inactive"
        }
    ],
    "publication_detail": {
        "frequency": "weekly",
        "time": 123456789,
        "recurrence": {
            "days": [
                2
            ],
            "start_date": 123456789
        }
    },
    "template_option": {
        "first_title": "First Title",
        "second_title": "Second Title",
        "tagline": {
            "show": true,
            "text": "Some tagline"
        },
        "top_logo": {
            "src": "s3://some/bucket/logo.png",
            "height": 40
        },
        "table_of_content": {
            "show": false,
            "text": "No TOC text"
        },
        "theme_color": "#123456",
        "show_icon": [
            "email",
            "feedback"
        ],
        "show_source": true,
        "show_curated_by_rane": true,
        "show_subscribe_unsubscribe": false,
        "show_manage_preference": false,
        "empty_category": {
            "show": true,
            "text": "Empty category text"
        },
        "empty_subcategory": {
            "show": false,
            "text": "Nothing to show for empty subcategories"
        },
        "footer_note": {
            "show": true,
            "text": "Footer notes"
        }
    },
    "internal_notes": "Some Internal Notes"
}

Response Object:

[
    {
        "name": "Brief 1",
        "display_name": "Brief 1 Display Name",
        "status": "active",
        "send_type": [
            "html"
        ],
        "category": [
            {
                "gid": "123-321",
                "display_name": "Cat 1 display name",
                "status": "active",
                "subcategory": [
                    {
                        "gid": "999-000",
                        "display_name": "SubCat 1 display name",
                        "status": "active"
                    },
                    {
                        "gid": "000-999",
                        "display_name": "SubCat 2 display name",
                        "status": "inactive"
                    }
                ]
            },
            {
                "gid": "321-123",
                "display_name": "Cat 2 display name",
                "status": "inactive"
            }
        ],
        "publication_detail": {
            "frequency": "weekly",
            "time": 123456789,
            "recurrence": {
                "days": [
                    2
                ],
                "start_date": 123456789
            }
        },
        "template_option": {
            "first_title": "First Title",
            "second_title": "Second Title",
            "tagline": {
                "show": true,
                "text": "Some tagline"
            },
            "top_logo": {
                "src": "s3://some/bucket/logo.png",
                "height": 40
            },
            "table_of_content": {
                "show": false,
                "text": "No TOC text"
            },
            "theme_color": "#123456",
            "show_icon": [
                "email",
                "feedback"
            ],
            "show_source": true,
            "show_curated_by_rane": true,
            "show_subscribe_unsubscribe": false,
            "show_manage_preference": false,
            "empty_category": {
                "show": true,
                "text": "Empty category text"
            },
            "empty_subcategory": {
                "show": false,
                "text": "Nothing to show for empty subcategories"
            },
            "footer_note": {
                "show": true,
                "text": "Footer notes"
            }
        },
        "internal_notes": "Some Internal Notes",
        "id": "62fcd04cb8a4cd1cb41009f7"
    }
]

PUT Method

Request

{
    "name": "New brief definition name",
    "display_name": "New brief definition display_name"
}

Response Object:

[
    {
        "name": "New brief definition name",
        "display_name": "New brief definition display_name",
        "status": "active",
        "send_type": [
            "html"
        ],
        "category": [
            {
                "gid": "123-321",
                "display_name": "Cat 1 display name",
                "status": "active",
                "subcategory": [
                    {
                        "gid": "999-000",
                        "display_name": "SubCat 1 display name",
                        "status": "active"
                    },
                    {
                        "gid": "000-999",
                        "display_name": "SubCat 2 display name",
                        "status": "inactive"
                    }
                ]
            },
            {
                "gid": "321-123",
                "display_name": "Cat 2 display name",
                "status": "inactive"
            }
        ],
        "publication_detail": {
            "frequency": "weekly",
            "time": 123456789,
            "recurrence": {
                "days": [
                    2
                ],
                "start_date": 123456789
            }
        },
        "template_option": {
            "first_title": "First Title",
            "second_title": "Second Title",
            "tagline": {
                "show": true,
                "text": "Some tagline"
            },
            "top_logo": {
                "src": "s3://some/bucket/logo.png",
                "height": 40
            },
            "table_of_content": {
                "show": false,
                "text": "No TOC text"
            },
            "theme_color": "#123456",
            "show_icon": [
                "email",
                "feedback"
            ],
            "show_source": true,
            "show_curated_by_rane": true,
            "show_subscribe_unsubscribe": false,
            "show_manage_preference": false,
            "empty_category": {
                "show": true,
                "text": "Empty category text"
            },
            "empty_subcategory": {
                "show": false,
                "text": "Nothing to show for empty subcategories"
            },
            "footer_note": {
                "show": true,
                "text": "Footer notes"
            }
        },
        "internal_notes": "Some Internal Notes",
        "id": "62fcd04cb8a4cd1cb41009f7"
    }
]

Content Type Resource

Class : v1.resources.content_type.content_type.ContentTypeResource

Note

Allowed Methods:

  • GET

GET Method

Request

Response:

[
    {
        "name": "Stratfor GRM Forecast",
        "slug": "grm_forecast",
        "legacy_id": 1,
        "id": "62e398846b7eb5a519e3919d"
    }
]

POST Method

Request

Warning

This endpoint is meant to be used only by the technical team to insert new content types. The payload is not checked and everything is inserted as sent in the payload.

{
    "name": "New Content Type",
    "slug": "new-content-type"
}

Response:

[
     {
         "name": "New Content Type",
         "slug": "new-content-type",
         "id": "62fcd4752d445e65126e2434"
     }
]

Content File Resource

Class : v1.resources.file.FileResource

Note

Allowed Methods:

  • GET

  • POST

Download File

Endpoint to download the file based on the s3 keys

Request

The s3_key could be public or private, based on that the response will have a regular or pre-signed url respectively.

Response:

This will download a file named as object_name

POST Method

This endpoint will be used by WYSIWYG editors and application to upload files like images, json, html pdf etc.

Request

There is two main variation right now:

  1. Public Files attachment_type=static or None
    • Uploads file to public s3 bucket, can be access directly

    • The path will be formatted by following template: {year}/{attachment_type}/{mime_type}/{object_name}.{extension}

      • year: automatically computed, represent current year eg: 2022

      • attachment_type: optional, default is static if not provided, and another one we support now is brief

      • mime_type: automatically computed, represent the mime type of the file being uploaded, if image is uploaded it will be image if pdf it will be application etc

      • object_name: optional: when not provided it will be md5 hash of the file, when provided api assumes user has sent a unique object name

      • extension: automatically computed, represents extension of the uploaded file

  2. Private Files attachment_type=brief
    • File will be uploaded in the private s3 bucket, cannot be access directly

    • The path will be formatted by following template: {year}/{attachment_type}/{brief_definition_slug}/{object_name}.{extension}

      • filename: this need to be set carefully, now we are using email.pdf, email.html and email-context.json. Based on this filename later application might have to choose the right attachment

      • year: automatically computed, represent current year eg: 2022

      • attachment_type: optional, default is static if not provided, and another one we support now is brief

      • brief_definition_slug: required, slug of the brief for which the resources are getting uploaded

      • object_name: optional: should be used <published-brief-gid>.extension

      • extension: automatically computed, represents extension of the uploaded file

More on the configuration that defines the attachment_type:

ATTACHMENT_TYPE_MAPPER = {
    'brief': {
        'private': True,
        'key_template': '{year}/{attachment_type}/{brief_definition_slug}/{object_name}.{extension}',
        'allowed_extension': ('json', 'html', 'pdf')
    },
    'static': {
        'private': False,
        'key_template': '{year}/{attachment_type}/{mime_type}/{object_name}.{extension}',
        'allowed_extension': ('jpeg', 'jpg', 'png', 'html', 'json', 'docx', 'doc', 'pdf')
    }
}
Details:
  • More attachment_type could be added in the future, right now attachment_type will be set as static if not provided

  • The private fields selects the public/private bucket accordingly

  • The allowed_extension field will validate the extension against the uploaded file

  • The ‘key_template’ will define what the s3 key will be for the file being uploaded

  • Developer can a new attachment_type without modifying/touching other part of the code

The is multipart form data, your header must have to have Content-Type: multipart/form-data; boundary=...

Sample http payload to upload a static files:

POST {{host}}/content/v1/file
X-Authorization-Token: {{api_token}}
X-USER-ID: {{user_id}}
X-REQUEST-FROM: {{request_from}}
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="my image.png"
Content-Type: image/png

< /Users/john-doe/Downloads/img.png
--WebAppBoundary--

Sample http payload to upload a brief related files:

POST {{host}}/content/v1/file
X-Authorization-Token: {{api_token}}
X-USER-ID: {{user_id}}
X-REQUEST-FROM: {{request_from}}
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
# attachment_type=brief will be used to select the right template in the code, which will then set the path of the file
Content-Disposition: form-data; name="attachment_type"
Content-Type: text/plain

brief
--WebAppBoundary
# s3_object_name can be passed when we wanted to have our custom object name in s3 other than default md5
Content-Disposition: form-data; name="s3_object_name"
Content-Type: text/plain

8-787878
--WebAppBoundary
# brief_definition_slug: this filed will added in between a path to separate brief specific resources
Content-Disposition: form-data; name="brief_definition_slug"
Content-Type: text/plain

risk-intel-brief
--WebAppBoundary
# File to be uploaded, the filename will be used to look for the specific files from attachment array later
# the name must be file name="file";
Content-Disposition: form-data; name="file"; filename="brief.pdf"
Content-Type: application/pdf

< /Users/rajan/Downloads/RANE Network Mail - Daily Cyber Brief.pdf
--WebAppBoundary--

Note:

  • Uploaded file must have fields name="file" and filename="<name-of-the-file.extension>"

  • Extension will be validated against defined ATTACHMENT_TYPE_MAPPER

Response Object:

The response will be s3 object. For eg:

{
  "user_id": "-1",
  "request_from": "DEVELOPER[Rajan]: HTTP Client Pycharm",
  "request_id": "content-request-id-e22d4b99-7adb-4a6c-92a1-5e605c34d322",
  "trace_id": "content-trace-id-333c2787-6ab2-44a0-80e5-a421e3b8b46f",
  "data": [
    {
      "attachment_type": "static",
      "uploaded_by": -1,
      "size": 15777,
      "name": "my image.png",
      "hash": "38ccb1eddd8bd5df1bcba61a461d0a7d",
      "mime_type": "image/png",
      "uploaded_on": 1669645137,
      "s3_key": "2022/static/image/38ccb1eddd8bd5df1bcba61a461d0a7d.png",
      "src": "https://content-v2-stag.s3.amazonaws.com/2022/static/image/38ccb1eddd8bd5df1bcba61a461d0a7d.png"
    }
  ]
}

Indices and tables