{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"09cbeb08-240d-4650-acad-ae127896c96a","name":"Brandworkz API (v1.6)","description":"The Brandworkz API allows you to interact with the data stored within your Brandworkz system. It is intended for developers who are writing standalone applications or integrations that incorporate content from Brandworkz.\n\n#### Prerequisites\n\nBefore getting started, a consumer ID and secret are required to be able to perform requests to the API.\n\n> If you do not have these access details yet, please contact your primary Brandworkz point of contact.\n\nThe easiest way to get started with the API is to click the [_Run in Postman_](https://www.getpostman.com/docs/run_button_ux) button present at the top of the documentation page and use the Postman App to send requests. Note that you need to have a Postman account and be logged in for the button to be present.\n\n# Overview\n\n1. The\n    \n    <a href=\"#authentication\">authentication</a>\n    \n    consists of calling an initial `/getAPIURL` endpoint, followed by requesting an access token.\n2. Such access token is then used for subsequent calls.\n3. The Brandworkz API will only respond to secured communications done over HTTPS. HTTP requests will send a `301` redirect to the corresponding HTTPS resources.\n4. The response to every request is sent in [JSON format](https://en.wikipedia.org/wiki/JSON) by default. Some endpoints have the option for an HTML response, too. This is specified by sending the `format` query parameter or the `Accept` header.\n5. In case an API request results in an error, it will return a code and a description about what happened. See the\n    \n    <a href=\"#error-handling\">Error Handling</a>\n    \n    section.\n    \n\n# Authentication\n\nThe Brandworkz API uses [OAuth 2.0](https://oauth.net/2/) + [JSON Web Tokens](https://jwt.io/). Please follow the below steps to successfully authenticate within the system.\n\n## Step 1: Get API details\n\nBefore authenticating, you will need to obtain your `client_id`, `api_url` and `api_version` from the `https://api.brandworkz.com/getAPIURL` endpoint. This is needed to request access tokens and call subsequent API endpoints.\n\nNote that /getAPIURL is a global endpoint which should always be called on [https://api.brandworkz.com/getAPIURL](https://api.brandworkz.com/getAPIURL) regardless of whether you are developing against a production or qa site and regardless of which geographical hosting location your site is in. However, for ALL subsequent endpoints you should call the domain and intial path returned from this call which may or may not be the same as the above domain.\n\nTo use this endpoint, you will need to pass the URL of your Brandworkz 'staging' or 'live' site via the `clientURL` parameter.\n\nFor example, [https://api.brandworkz.com/getAPIURL?clientURL=mycompanyname.brandworkz.com](https://api.brandworkz.com/getAPIURL?clientURL=mycompanyname.brandworkz.com)  \nand below is an example of the JSON response:\n\n``` json\n{\n    \"result\": {\n        \"message\": \"Success\",\n        \"code\": 0\n    },\n    \"data\": {\n        \"api_url\": \"https://us-api.brandworkz.com\",\n        \"client_id\": \"brandworkz_mycompanyname\",\n        \"version\": \"1.6\"\n    }\n}\n\n```\n\n`api_url`: The base URL that needs to be used for all subsequent endpoint API calls.\n\n`client_id`: This is an identifier, specific for each client.\n\n`api_version`: The current API version.\n\n> **Important:** These three values must always be set dynamically using the `getAPIURL` call and never be hard-coded. If you hardcode any of these then either subsequent calls won't work at all or they will stop working at some point in the future when we retire the current API version.\n\nThese three variables should be used at the beginning of every call as follows:  \n`{{api_url}}/v{{api_version}}/{{client_id}}/endpoint`\n\n> **Tip:** For ease of use inside Postman, you should store the above as [environment variables](https://www.getpostman.com/docs/environments). Then always run the `/getAPIURL` followed by the `/oauth/token` call before making any other API calls. More info on setting up Postman variables can be found [here](https://developers.onelogin.com/api-docs/1/getting-started/postman-collections).\n\n## Step 2: Get a token\n\nOnce you have the API details, you can either request a token directly (2a below), or you can use the authentication code flow to get a code and request a token at a later time (2b below).  \nIf your Brandworkz instance has SAML SSO users then you must use code flow.\n\nNote that the below `/oauth/...` authorisation endpoints are different from the functional endpoints as they do not have the api_version and client_id specified in the path. They are unversioned and should have the client_id passed in through the client DB parameter as per below. However you should still use the API domain from /getAPIURL\n\n### 2a: Request an access token directly\n\nOnce you have the above API details and your consumer ID and secret as mentioned in the prerequisites section, you will be able to request an access token as follows:\n\n> Please bear in mind that this endpoint call is a POST and can't be pasted in a browser, so this is a [cURL](https://curl.haxx.se/) command that can be executed in a console.\n\n```\ncurl \\\\\n    -u {{consumer_id}}:{{consumer_secret}} \\\\\n    -X POST \"{{api_url}}/oauth/token\" \\\\\n    -H \"Accept: application/json;charset=UTF-8\" \\\\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\\\n    -d \"grant_type=password&client_db={{client_id}}&username={{user_login}}&password={{user_password}}\"\n\n```\n\nFor example:\n\n```\ncurl \\\\\n    -u mybrandsite-live:j9dueY5RReqa95dMq \\\\\n    -X POST \"https://us-api.brandworkz.com/oauth/token\" \\\\\n    -H \"Accept: application/json;charset=UTF-8\" \\\\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\\\n    -d \"grant_type=password&client_db=brandworkz_mycompanyname&username=bobbySmith&password=dl_8MrTjja\"\n\n```\n\n`user_login` and `user_password` must be an existing user on your site.\n\nAn access token will be returned as part of the response:\n\n``` json\n{\n  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjZGIiOiJicmFuZHdvcmt6X215YnJhbmRzaXRlIi...\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjZGIiOiJicmFuZHdvcmt6X215YnJhbmRzaXRlIi...\",\n  \"expires_in\": 1200,\n  \"scope\": \"read write\",\n  \"cdb\": \"brandworkz_mycompanyname\",\n  \"uid\": 5081,\n  \"sid\": \"b68c2984-7aa7-408f-89e4-3a5fde42ae9a\",\n  \"jti\": \"78c48e66-6d4a-4ea9-a3e5-6cd1dba30b29\"\n}\n\n```\n\n### 2b: Using authentication code flow\n\n#### Initial Endpoint\n\nIn order to get a code, the user's browser should be redirected to an initial endpoint to start the process.\n\nThe initial endpoint is: `{{api_url}}/oauth/authorize`\n\nThis endpoint requires a number of parameters, which are:\n\n- clientDb - This is the \"client_id\" from getAPIURL\n- response_type - This should have the value, \"code\" to indicate that you wish to use the authentication code flow process to authenticate.\n- client_id - Your consumer Id, i.e. NOT the \"client_id\" returned from getAPIURL.\n- scope - The scope of the authentication, this should be set to, \"read\".\n- redirect_uri - This is the URI that the code will be sent to once the user has authenticated and approved the request.\n    \n\nEndpoint example:  \n`{{api_url}}/oauth/authorize?clientDb={{client_id}}&response_type=code&client_id={{consumerID}&scope=read&redirect_uri={{Your Redirect URI, to process the Auth code}}`\n\nAfter visiting that endpoint, the user's browser will be redirected to our login form page, where they can enter their Brandworkz login credentials.\n\n#### Approval\n\nAfter the user has authenticated, they are redirected to an approval screen, as they will need to approve the use of the integration that initiated the process.\n\nThe user will need to select \"Authorize\", in order to proceed and generate a code.\n\nIf the user selects \"Deny\" from the approval screen, then they will be redirected to the initial redirect URI, with the following parameters:\n\n`[Your Redirect URI]/?error=access_denied&error_description=User denied access`\n\nWhen the user selects \"Authorize\", they will then get redirected to the initial redirect URI, but with the code attached as a parameter, e.g.  \n`[Your Redirect URI]/?code=qRcX8q`\n\n#### Using the code\n\nThe code generated in the previous step can then be used to generate a token. For example, using curl:\n\n`curl -u \"[Consumer ID]:[Secret]\" -X POST \"[API URL]/oauth/token\" -H \"Accept: application/json;charset=UTF-8\" -H \"Content-Type: application/x-www-form-urlencoded\" -d 'grant_type=authorization_code&client_db=[Client DB]>&code=qRcX8q&redirect_uri=[Your Redirect URI]'`\n\nAll of the parameters in the call to get the token should match those that were given in the initial endpoint, although note that in the above call `client_db` should be used as the parameter name as opposed to `clientDb` in `/oauth/authorize`\n\n## Step 3: Use the access token\n\nIn order to make subsequent endpoint calls which require authentication, the only thing you have to do is to specify the access token as the `Authorization` request header, as follows:\n\n`Authorization: Bearer {{access_token}}`\n\nSuch access token will be valid for the number of seconds specified in `expires_in` when requesting it. In order to renew it, you just need to use the refresh token changing the grant type. For more information, please check out the [official OAuth 2.0 documentation](https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/) on how to do this.\n\n# Search and Browse\n\nIf you are doing an integration where the end-user needs to search and/or browse for assets, e.g. to insert images or videos ad-hoc into a 3rd party CMS or eCommerce app, then there are two ways to do it:\n\n1. The preferred way is to use our out-of-the-box UI for this via the `/assetInsert` API endpoint\n2. If for any reason, you can't use the previous option, you can construct a search/browse UI \"manually\" via the `/simpleSearch` endpoint.\n    \n\n## Search/Browse UI via /assetInsert\n\nThe `/assetinsert` endpoint will return a complete HTML/React app very similar to the main search in the web-UI, complete with keyword search, search facets, folder browsing, asset detail view, and download options. This app can be embedded in e.g. a pop-up or iframe in the 3rd party app, and have parameters to limit it to show only certain filetypes or files uploaded by the end-user themselves, and allowing either single-file or multi-file selection. When the user has selected one or more assets, the app will do a call-back to the calling 3rd party app with json info on the selected files.\n\nThis is by far the preferred option for this use-case as it will be quicker to implement, provides a rich search/browse experience, and will automatically receive feature enhancements from us.\n\nYou can see further detail on the endpoint below under the \"UI\" section as well as example code for how to implement it in either jQuery and JECMAScript6+WebPack here: [https://github.com/bwkz/assetInsert-integration-examples](https://github.com/bwkz/assetInsert-integration-examples)\n\n## Search/Browse UI via /simpleSearch\n\nThe `/simpleSearch` endpoint can of course as the name implies be used for creating a simple Google-style search feature, but it can - and should - also be used for manually constructing a folder-hierarchy browse feature if you need this, and can't use /assetInsert as described above.\n\n### Search UI via /simpleSearch\n\nYou will need to create your own text input box which on submit performs a GET like so with `XXXX` being the phrase the end-user types in\n\n```\n/simpleSearch?searchterm=XXXX\n\n```\n\nThe result will be something like this:\n\n``` json\n{\n\"result\":{\n\"message\":\"Success\",\n\"code\":0\n},\n\"searchResult\":{\n\"total\":2,\n\"hits\":[\n{\n\"_source\":{\n\"extendedKeywords\":\"\",\n\"serialNumber\":2001,\n\"description\":\"\",\n\"version\":1,\n\"thumbnailUrlCdn\":\"https://cdn.domain.com/assetThumbnails/0020/2001_1_thumbnail_320x320_page1_157792.jpg\",\n\"title\":\"Brandworkz-Logo-Landscape-RGB-darkText\",\n\"objectURL\":\"/BMS/asset/views/?artwork_ID=2001&category=96\"\n},\n\"_type\":\"asset\",\n\"_id\":\"d76e2bc0-7933-4cc2-b4b0-3b8183279758\",\n\"_score\":13.55542\n},\n{\n\"_source\":{\n\"extendedKeywords\":\"\",\n\"serialNumber\":3697,\n\"description\":\"\",\n\"version\":1,\n\"thumbnailUrlCdn\":\"https://cdn.domain.com/assetThumbnails/0036/3697_1_thumbnail_320x320_page1_144462.jpg\",\n\"title\":\"Brandworkz Logo Landscape RGB Neg\",\n\"objectURL\":\"/BMS/asset/views/?artwork_ID=3697&category=95\"\n},\n\"_type\":\"asset\",\n\"_id\":\"1d91d44f-9f10-44d0-bcb5-8d2bad4816dc\",\n\"_score\":8.396609\n}\n],\n\"max_score\":null\n}\n}\n\n```\n\nNote the following in relation to the response structure above:\n\n- `searchResult.total` is of course the total number of total hits from a particular search query and the `searchResult.hits` array are the actual hits. However, the hits array is limited to only show a max number of hits so may not match the total. See the guidance on the `from` and `size` parameters further down for implementing paging.\n- for each entry in the `searchResult.hits` array:\n- `_id` is the guid for the result. You should if possible always use the GUID even though for certain types like assets, a sequential serialnumber/ID is also returned. There are some older API calls which will expect the sequential ID but these are likely to be retired in the future as we move towards using only GUIDs everywhere.\n- `files.GUID._source` contains all other information for a result. See info on the `sourceFields` parameter further down to return additional metadata if you need it.\n- `extendedKeywords` : This is a synthesized read-only field useful for outputting a simplified keywords list. It consists of a concatenation of:\n- Content of field with a \"keywords\" systemref if there is one\n- Values from all multiple-choice fields (select, tick, radio, multi, hierarchical)\n- Text from any single-line text fields if they haven't got a systemref of \"description\"\n- `description` : Will show the content of any field with a systemref of 'description'\n- thumbnailUrlCdn : Link to a small thumbnail sized to a 320x320 bounding box.\n- `objectURL` : a link to the asset within the Brandworkz Web-UI\n    \n\nThe endpoint is permission-aware so will only return results which the end-user has access to, but by default it will return results from everywhere in the system as well as all asset types so you may want to limit down on these as well:\n\n- `categoryGUID` : If this is passed in then only descendants of that category/folder will be returned. Tip: The sysadmin can see the categoryGUID of a folder in the Brandworkz Web-UI if they browse to the folder and click on Properties.\n- `assetType` : By default all of these types/categories are returned: Image, Video, Audio, Document, Folder, Webpage, Editable template (W2P template), User artwork (artwork created from W2P template). If for instance you are creating an integration for a CMS then it's likely that you wouldn't want to show folders, webpages and web-to-publish templates/artworks, but only files and would therefore specify `assetType=Image,Video,Audio,Document` Note that the options are case sensitive.\n- `fileType` : In some circumstances you may need to limit the filetypes down even further than just the asset categories/types above to specific file suffixes. If for instance you were creating a document integration where only PowerPoint files should show up in the results you could specify `fileType=pptx,potx,potm,ppsx,ppsm,pptm,ppam,ppt,pot,pps,ppm` These options are case-insensitive.\n    \n\nYou will most likely also need to use these two parameters:\n\n- `from` : This is for implementing paging if there are more results than will fit on one page. The default number of search results returned for a page is 50 as set in the optional `size` parameter. If there are more than 50 hits, then for page 2 you need to pass `from=50` for page 3 `from=100` and so forth (note that this is zero-based). You can check how many hits there are from a query in the `searchResult.total` node of the response. The maximum value you can set `size` to is 500, but of course the higher you set this, the slower your UI will be, especially if you are loading thumbnails for the results as well.\n- `sourceFields` : This determines how much file information and metadata you will get back for each hit. By default it will return a good base selection of fields such as title, thumbnailUrlCdn, etc. so start there. If you need more information back for an asset, such as custom metadata, pixel sizes, then _temporarily_ set `sourceFields=all`. This will return all metadata including custom metadata. You can then specify all of the fieldnames you need as a list in sourceFields and these will be returned. Note that it's very important to not use sourceFields=all in production because this will e.g. also return the document fulltext so the response can run to many megabytes.\n    \n\nNote that you can also create more complex search queries via the `/search` endpoint, for instance if you wanted to return search facets/filtes. This takes native Elastic json query format and executes it against your Elastic search index after applying the end-users permissions. In order to use this you will therefore need to have a good understanding of both the Elastic query syntax as well as the internal structure of your Brandworkz search index.\n\n### Browse UI via /simpleSearch\n\nIf you need to manually create an OS-style folder-browse UI via /simpleSearch then first go through how to create a search UI with this endpoint above. This will give you a grounding in many of the input parameters you will also need for a browse UI.\n\nTypically you will want to start by outputting all folders and files at the root of the folder hierarchy. In order to only return direct children of a particular folder is to use the `parentCategoryGUID` input parameter.\n\nIn order to get the GUID of the root category use this:\n\n```\nGET /getCategoryInfo?categoryID=0\n\n```\n\n...and the guid will be returned in the `categoryGuid` node.\n\nThen use the returned GUID for the root node like so:\n\n```\nGET /simpleSearch?parentCategoryGUID=1B35C48F-03EA-4DB3-99B2-F7C598979E68&assetType=Folder,Webpage,Image,Video,Audio,Document\n\n```\n\nThe response structure will be the same as shown further up under \"Search UI via /simpleSearch\" but note that you may get both Folders, WebPages as well as files (image, Video, Audio, Document) in the results.\n\n- `Folders` and `WebPages` : Both of these will return as `_type=folder`. This is because conceptually they are the same, i.e. nodes in a hierarchy. A webpage is essentially a folder with a CMS template attached to it. Note that even though Webpages can't directly contain assets they can have sub-folders which may have assets in so when doing a browse-UI you should always include these in assetType.\n- `Image,Video,Audio,Document` You may of course want to limit this down to only some of these asset categories.\n- You will probably want to represent each folder, page and asset type with distinct icons in your UI. If this is the case you should include `assetType` in the list of `sourceFields` you specify as you can then pick up on this in the response to show the right icon for each type.\n- If parentCategoryGUID is specified, then the ranking of the result will be modified from the default internal Elastic \"ranking\" and instead will be returned with folders/webpages first and then assets, both alphabetically.\n- If you need to limit down to specific file filetypes/suffixes via the `fileType` parameter then note that folders and webpages will not be returned and in this case you will need to make two calls every time the end-user browses to a folder, one for the folders/pages, and another for the files of the specific type.\n    \n\nThe above will return a number of folder/webpage and file hits at the root. When the user clicks on one of these then you will probably want to do the following:\n\n- **Folders/Webpages** : Simply do an identical call to the root folder one above but exchange the parentCategoryGUID with the GUID of the folder as returned in `_id`\n- **Files** : You may have everything you need in the `_source` sourceFields as returned by the original query, but you don't want to make this too bloated so if you need to show a variety of asset metadata when an asset is clicked then perform another call to /simpleSearch specifying the extra sourceFields you need and entering the asset GUID as returned in `_id` for the hit into the `searchTerm` field\n    \n\n# Uploading files\n\nWhen uploading files to Brandworkz via the API you can do this in two ways.\n\n1. Upload the whole file in one PUT action.\n2. Split the file into parts/chunks, upload each chunk and then assemble the uploaded chunks after uploading.\n    \n\nWe recommend that you implement both types depending on the size of the file, with single-file upload for smaller files and multi-part/chunked upload for large files as you will then be covered for all file sizes now and in the future. In the Brandworkz web-UI we start to chunk uploads for files that are larger than 15MB and this is also our recommendation for you.\n\nHowever, if you know that your integration won't be uploading large files such as HD videos, Photoshop files, large PowerPoints, etc then you can opt to only implement the single-file upload, although note that even if you have a fast internet connection then these uploads may start failing if the files go above 100-200MB, and doing very large PUTs may also be disallowed by a security device on your corporate network. The theoretical limit for a single-file PUT is 5GB, but if you have filesizes like that then you definitely need to implement chunked upload.\n\nUploading a single file vs multi-part is controlled via the `uploadType` parameter when calling the initial `/createUploadPath` API endpoint.\n\n1. If you don't specify uploadType then you will be returned a single-file upload URL for files smaller than **15MB**, and an array of upload links for files larger than this, for uploading each chunk to. The array also specifies how many bytes each chunk should be.\n2. If you specify `single-upload` then you will get a single upload URL returned to PUT the file to.\n3. If you specify `multipart-upload` then you will be returned an array of upload links including what the byte size of each chunk should be. Each chunk will be 15MB with the remainder in the last chunk. E.g. a 32MB file will return three upload URLs, the first two for 15MB chunks each and the last one for the remaining 2MB. Note however, that if the file is so large that a 15MB chunk size would result in more than 200 upload links, the chunksize will be increased. Therefore, the part byte sizes are not constants and will need to be read from the response returned by the initial /createUploadPath call - see below.\n    \n\n_(Note that if you use Postman for your API development then this will unfortunately not work for the actual file uploads/PUTs as Postman adds additional headers which stops the authentication working with the AWS S3 signed upload url returned)_\n\n## Upload the whole file in one action\n\nThe steps for this are in summary as follows:\n\n1. Generate an upload link via the /createUploadPath endpoint\n2. Upload the file to the upload link via PUT\n3. Import the file into Brandworkz via the /importAsset endpoint\n    \n\n### 1\\. Generate an upload link via the /createUploadPath endpoint for single-file upload\n\nThis will return the information needed to upload the file to S3, and also to import it in a later call. At a minimum you need to specify these in the request body:\n\n- **fileName** (string) The name of the file being uploaded incl suffix. e.g. myLogo.png.\n- **fileSize**(numeric) The size of that file in bytes - e.g. 33554432 (a 32MB file)\n- **categoryGuid** (string) The GUID of the folder that you're going to upload into. The category GUID is returned by other endpoints in the API, e.g. `/simpleSearch` and `/getCategoryInfo`\n- **uploadType**(enum, _optional_) Can be either `single-upload` or `multipart-upload` As outlined above, this will control if this function returns a single link for uploading the entire file in one PUT, or an array of links for uploading the file in chunks. If this isn't specified then a single upload link will be returned for files of less than 15MB, and an array of upload links for each 15MB (or larger) chunk for files larger than this. In this example `single-upload` should be specified.\n    \n\nYou can optionally also specify these:\n\n- **assetGuid** (string, _optional_) If you would like to upload a new file/version to an existing asset then specify the assetGuid of the asset you would like to upload this new version to. Also, if you are uploading a custom thumbnail to an existing asset then you must specify this.\n- **isCustomThumbnail** (boolean, _optional_) If this is set to true then the path returned will be for uploading a custom thumbnail/preview to an existing asset. This is useful for filetypes where we may not auto-generate a visual preview, e.g. some 3D files. If this is set to true then you must specify a valid assetGuid, and also set the equivalent parameter to true in the subsequent /importAsset endpoint.\n    \n\nAn example request body is this:\n\n``` json\n{\n\"filename\": \"myLogo.png\",\n\"filesize\": 33554432,\n\"categoryGuid\": \"a4428547-14f9-4a0e-bb53-f7c3a06c7a6e\",\n\"uploadType\": \"single-upload\"\n}\n\n```\n\nAnd the response will be similar to this:\n\n``` json\n{\n\"data\":{\n\"categoryGuid\":\"a4428547-14f9-4a0e-bb53-f7c3a06c7a6e\",\n\"assetId\":10152,\n\"assetVersion\":1,\n\"keyName\":\"originals/0101/myLogo_010152_001.png\",\n\"uploadDetails\":{\n\"type\":\"single-upload\",\n\"url\":\"https://bwkz-bms-euprod-tenant-assets.s3-accelerate.amazonaws.com/clientname/assets/originals/0135/myLogo_010152_001.png?AWSAccessKeyId=ASIAQ2YO7IPIP6YGS57P&Signature=HaZcmoTVI7KYRPVdt...&Expires=1601988910\"\n}\n},\n\"result\":{\n\"message\":\"Success\",\n\"status\":0\n}\n}\n\n```\n\nNotes to the above response:\n\n- Before going further, first check for success. Do this by checking for result.status=0 or alternatively for a 200 HTTP success code.\n- If there is an error then the error message will be in the result.message json node.\n- The upload link is time limited. 15 minutes, or correspondingly longer the larger the file is.\n- Keep the information returned from this endpoint, as we will need to use it in subsequent calls.\n    \n\n### 2\\. Upload the file\n\nUpload the entire file via PUT to URL returned in the data.uploadDetails.url node in the /createUploadPath endpoint above.\n\nAs mentioned above, note that you during development can't use Postman for this as it adds headers incompatible with AWS S3 signed URLs.\n\nCheck for a 200 OK HTTP response from the PUT to validate that the file uploaded successfully.\n\n### 3\\. Import the file into Brandworkz via the /importAsset endpoint\n\nFinally import the uploaded file into Brandworkz by calling the `/importAsset` endpoint\n\nAt a minimum you need to specify these in the request body:\n\n- **categoryGuid** (string) must be the same categoryGuid specified in the /createUploadPath call\n- **keyName** (string) As returned from /createUploadPath in the `data.keyname` value\n- **originalFilename** (string) Pass the same value as per `fileName` in the /createUploadPath call\n- **assetId** (string) As returned from /createUploadPath in the `data.assetId` value\n- **assetVersion** (string) As returned from /createUploadPath in the `data.assetVersion` value\n- **filesize** (numeric) The filesize in bytes\n    \n\nContinuing our example from above with the myLogo.png file the request body would look like this:\n\n``` json\n{\n\"categoryGuid\": \"a4428547-14f9-4a0e-bb53-f7c3a06c7a6e\",\n\"keyName\": \"originals/0101/myLogo_010152_001.png\",\n\"originalFilename\": \"myLogo.png\",\n\"assetId\": 10152,\n\"assetVersion\": 1,\n\"fileSize\": 33554432\n}\n\n```\n\nIf the file imports correctly, then you will get a response similar to this:\n\n``` json\n{\n\"result\": {\n\"status\": 0,\n\"message\": \"Success\"\n},\n\"data\": {\n\"binaryIdenticalToGuid\": \"\",\n\"shortcutCreated\": 0,\n\"md5\": \"99a3ceafafd891df92a5847e603d60aa\",\n\"pixelwidth\": 7016,\n\"pixelheight\": 4961,\n\"resolution\": 300,\n\"imageformat\": \"CMYK-32\",\n\"pagecount\": 1,\n\"durationInSeconds\": 0,\n\"disksizeBytes\": 33554432,\n\"assetSerialNumber\": 10152,\n\"assetVersion\": 1,\n\"assetGuid\": \"272c757f-01a6-4d72-9eb1-328d82a7ca59\",\n\"assetVersionGuid\": \"7f449978-b7e4-4537-a208-4eabc7867705\",\n\"assetTitle\": \"myLogo\",\n\"nameClash\": false\n}\n}\n\n```\n\nNotes to the above response:\n\n- As per earlier calls, check for success. Do this by checking for `result.status=0` or alternatively for a `200 HTTP success` code. If unsuccessful, the reason for the issue will be in result.message.\n- Note that files may fail to import as expected behaviour. For instance if you try to upload an .exe file this will not import for security reasons. You may also have file deduplication enabled and the same binary file is already on the system in which case the file will be turned into a shortcut of the original. In most cases result.status = 1 means that there have been an error and result.status = 2 means that the file hasn't important for another reason. In both cases the reason should be returned in `result.message`.\n- In order to return a response as soon as possible from this call, only the essential asset information is discovered and returned. Further asynchronous tasks will be performed after the response, for instance adding the asset to the search index, creating thumbnails and previews, extracting document text, discovering colours, etc. Therefore, if you call e.g. `/simpleSearch` on the returned assetGuid immediately after upload it may not be present or may not be fully populated. The asynchronous data should be fully populated after 30 seconds, although note that documentfulltext from documents and colour extraction from images can take up to 2 minutes. Also note that even though you can query the API and get thumbnail links back after 30 seconds, the actual image files may not be generated until later.\n- In extension to the above point, note that any embedded metadata in images - e.g. keywords, description, etc - is extracted synchronously before the /importAsset responds. This means that it is safe to immediately call the `POST /saveMetadata` endpoint after this if you need to assign metadata to the uploaded file.\n    \n\nThe data nodes in the above example are guaranteed to be returned regardless of filetype, although some of them may be empty, e.g. if you upload an audio file then the pixelwidth/height will of course be empty. Note the following on these response nodes:\n\n- **shortcutCreated** (bool): If you have file deduplication enabled in the system preferences, and the file you are uploading is already present somewhere else in the system - based on an MD5 checksum match - then this will be true (1).\n- **binaryIdenticalToGuid** (string): if shortcutCreated = 1 then this will contain the assetGuid of the file on the system which the uploaded file is identical to.\n- **md5** (string): Note that this will only be returned if asset deduplication is enabled in system preferences. You can use this to verify with absolute certainty that the file uploaded successfully if you calculate the md5 checksum of the original file and then compare it with this value.\n- **disksizeBytes** (integer): number of bytes of the file uploaded. Should match the filesize of the original file, i.e. can be used as a quickcheck to ensure that the file uploaded intact.\n- **pixelwidth** (integer): pixelwidth for images and videos. Empty if other types\n- **pixelheight** (integer): pixelheight for images and videos. Empty if other types\n- **resolution** (integer): resolution in dpi for images. Empty if other types\n- **imageformat** (string): the colourDepth/system for images. Typical values are \"RGB-24\", \"RGB-48\", \"RGB-96\", \"CMYK-32\", \"CMYK-64\", \"CMYK-128\"\n- **pagecount** (integer): The page or slide count for documents and presentations. 1 for all other filetypes.\n- **durationInSeconds** (decimal): duration for videos in second-decimal format\n- **assetSerialNumber** (integer): The human-friendly Brandworkz serial number. A sequential number which is incremented every time a new file is uploaded. Note that although this is guaranteed to be unique within your system, you should if possible use the assetGuid in preference to this for storing back in your own system or for further actions on the asset.\n- **assetVersion** (integer): Will be 1 for new assets, and subsequent numbers if uploading new versions of existing assets.\n- **assetGuid** (guid): The main identifier for a Brandworkz asset. In your integration you should store this GUID back in your own system for future reference/API calls on that asset. Note however that this guid is version independent and when used will return the details of the latest version of this asset - which for most use cases is what you would want. However, you may want to store the assetVersion back in your system as well for future reference.\n- **assetVersionGuid** (guid): The asset's version-specific Guid. This is mainly used for internal purposes at present but may be used in future public API calls.\n- **assetTitle** (string): The title of the asset. Will for new assets initially be based on the filename minus the file suffix. Note that if you upload new versions of existing assets then the assetTitle will remain and not change to the filename of the new file if this is different to the original version. See also 'nameClash' below.\n- **nameClash** (bool): If you upload a file to a folder which already have an asset with the same Title as what the new one would get based on it's filename then (2) will be appended to it. For instance if you upload \"myLogo.png\" and there is already an asset in the same folder called \"myLogo\" then the new asset will be named \"myLogo (2)\" and so forth, and this will be returned in the `assetTitle` above.\n    \n\n### Completion\n\nIf all of the responses returned successfully, you should now be able to see the file in the system in the folder that you specified!\n\nTypical subsequent API calls after uploading are:\n\n- `POST /saveMetadata` for assigning/changing the asset's metadata.\n- `/simpleSearch`for getting further information back on the asset beyond what's returned in the /importAsset response. See notes on the asynch nature of this further up.\n    \n\n## Upload files in separate chunks/parts\n\nThe steps for this are in summary as follows:\n\n1. Generate the upload links via the /createUploadPath endpoint\n2. Split the file into chunks and then upload each one via the upload links returned via PUT\n3. Assemble the chunks back into a file after uploading all chunks\n4. Import the file into Brandworkz via the /importAsset endpoint\n    \n\n### 1\\. Generate the upload links via the /createUploadPath endpoint\n\nThe input parameters are identical to the ones outlined under the single-file upload above apart from the fact that the `uploadType` should be `multipart-upload` - or if `uploadType` isn't specified and the file is larger than 15MB\n\nThe response is somewhat different to the single-file response and looks like this for our imaginary 32MB myLogo.png file:\n\n``` json\n{\n\"data\":{\n\"categoryGuid\":\"a4428547-14f9-4a0e-bb53-f7c3a06c7a6e\",\n\"assetId\":10152,\n\"assetVersion\":1,\n\"keyName\":\"originals/0101/myLogo_010152_001.png\",\n\"uploadDetails\":{\n\"uploadId\":\"9lI4NQl20DGxnpYreJV6f3EHg7.CaiEGHj4dAOGdk1VAK7lDOgJRzIQ.9N5s35l.l6NQRsqtMeYckhHsoblYW01QKxb3rjnn4bZR48e2pOggj3Cj3y5e2S6VBtvXQbl3ahFXaL.5EAC5wXhCoxacaiCrcME3J5b7RxTrKj62XZI-\",\n\"urls\":[\n\"https://bwkz-bms-qa-tenant-assets.s3-accelerate.amazonaws.com/example_client/assets/originals/0101/myLogo_010152_001.png?uploadId=9lI4NQl20DGxnpYreJV6f3EHg7.CaiEGHj4dAOGdk1VAK7lDOgJRzIQ.9N5s35l.l6NQRsqtMeYckhHsoblYW01QKxb3rjnn4bZR48e2pOggj3Cj3y5e2S6VBtvXQbl3ahFXaL.5EAC5wXhCoxacaiCrcME3J5b7RxTrKj62XZI-&partNumber=1&AWSAccessKeyId=ASIAQ2YO7IPILRUZ3QGH&Signature=9OlMOePJ4L6ZYzzRV7zJ0rQy2Yc=&x-amz-security-token=IQoJb3...&Expires=1601997174\",\n\"https://bwkz-bms-qa-tenant-assets.s3-accelerate.amazonaws.com/example_client/assets/originals/0101/myLogo_010152_001.png?uploadId=9lI4NQl20DGxnpYreJV6f3EHg7.CaiEGHj4dAOGdk1VAK7lDOgJRzIQ.9N5s35l.l6NQRsqtMeYckhHsoblYW01QKxb3rjnn4bZR48e2pOggj3Cj3y5e2S6VBtvXQbl3ahFXaL.5EAC5wXhCoxacaiCrcME3J5b7RxTrKj62XZI-&partNumber=2&AWSAccessKeyId=ASIAQ2YO7IPILRUZ3QGH&Signature=aRu4O3pPg2w2tW+eEeoJhgG0Y7Q=&x-amz-security-token=IQoJb3...&Expires=1601997174\",\n\"https://bwkz-bms-qa-tenant-assets.s3-accelerate.amazonaws.com/example_client/assets/originals/0101/myLogo_010152_001.png?uploadId=9lI4NQl20DGxnpYreJV6f3EHg7.CaiEGHj4dAOGdk1VAK7lDOgJRzIQ.9N5s35l.l6NQRsqtMeYckhHsoblYW01QKxb3rjnn4bZR48e2pOggj3Cj3y5e2S6VBtvXQbl3ahFXaL.5EAC5wXhCoxacaiCrcME3J5b7RxTrKj62XZI-&partNumber=3&AWSAccessKeyId=ASIAQ2YO7IPILRUZ3QGH&Signature=l9M9SVbEJkBEQtF0IbNKdhKG00s=&x-amz-security-token=IQoJb3...&Expires=1601997174\"\n],\n\"mainChunkSize\":15728640,\n\"finalChunkSize\":2097152,\n\"type\":\"multipart-upload\",\n\"chunkNo\":3\n}\n},\n\"result\":{\n\"message\":\"Success\",\n\"status\":0\n}\n}\n\n```\n\nIncluded in this response is the mainChunkSize and the finalChunkSize, these values are in bytes. These relate to the size of the chunks that should be uploaded to each URL. The final URL in the list should have a chunk corresponding to the finalChunkSize.\n\nIn the example above, the chunkNo indicates that there should be 3 chunks in total: 2 with a size of 15728640 bytes each, and 1 of 2097152 bytes.\n\nAlso note that the three upload URLs returned in the data.uploadDetails.urls array each have a `partNumber` URL parameter which corresponds to the chunk that should be used against it. The returned array will always be in sequence, i.e. partNumber will always be 1 for the first link and so forth.\n\nYou will also need to keep track of the data.uploadId value returned as you need this later to assemble the files.\n\n### 2\\. Split the file into chunks and then upload each one via the upload links returned via PUT\n\nNow that we have generated the links to upload to, we now need to actually upload the file chunks.\n\nThe chunks need to be sent with a HTTP PUT request.\n\nWhen uploading chunks, then each chunk should be uploaded to the corresponding URL in the list returned by /createUploadPath as described above.\n\nDuring development you may want to do the uploads from the command line. On Linux/Apple based systems, you can use the curl command, e.g.\n\n```\ncurl -v --upload-file x1.bin \"https://bwkz-bms-qa-tenant-assets.s3-accelerate.amazonaws.com/example_client/assets/originals/0101/myLogo_010152_001.png?uploadId=9lI4NQl20DGxnpYreJV6f3EHg7.CaiEGHj4dAOGdk1VAK7lDOgJRzIQ.9N5s35l.l6NQRsqtMeYckhHsoblYW01QKxb3rjnn4bZR48e2pOggj3Cj3y5e2S6VBtvXQbl3ahFXaL.5EAC5wXhCoxacaiCrcME3J5b7RxTrKj62XZI-&partNumber=1&AWSAccessKeyId=ASIAQ2YO7IPILRUZ3QGH&Signature=9OlMOePJ4L6ZYzzRV7zJ0rQy2Yc=&x-amz-security-token=IQoJb3...&Expires=1601997174\"\n\n```\n\nIn this example, \"x1.bin\" is the name of the chunk (see the split command reference in Chunking) and the link is the first link in the list of the /createUploadPath response.\n\nCurl is using the -v option here, so that we can see the headers returned by the call. We will need the ETag header returned in the response from every PUT call, as they will be used to assemble the chunks in the next call.\n\nRepeat the curl command for each chunk/URL of the file, and keep a record of all the ETag headers in the responses.\n\nWhen uploading programmatically you will also need to capture the Etag response from each chunk as you will need those to assemble the parts later.\n\nThe method of chunking a file is completely up to you, and can vary from system to system. There is no single way of doing it, and you should pick the most appropriate method for your use case and programming language.\n\nFor Linux and Apple based systems, there is the split command, e.g.\n\n```\nsplit -b 15728640 --numeric-suffixes=1 --suffix-length=1 --additional-suffix=\".bin\" myLogo.png\n\n```\n\nThis would generate a number of files with the .bin extension of the right sizes. e.g x1.bin.\n\n### 3\\. Assemble the chunks back into a file\n\nTo do this you call the `/assemble` endpoint with the following values for the request body:\n\n- **objectKey**: As returned in `keyName` from the initial `/createUploadPath` response\n- **uploadId**: As returned in `data.uploadId` from the initial `/createUploadPath` response\n- **eTag**(s): The eTag returned from each PUT upload for the chunks. Note that you will get \"ETag\" returned in the headers, but you need to use \"eTag\" in the json below.\n    \n\nThe json body should look like this:\n\n``` json\n{\n\"objectKey\": \"originals/0101/myLogo_010152_001.png\",\n\"uploadId\": \"KCTf7nos7bjhqk9w6y7wxXmQNsJWU1565Ul5bo.bfSfZM6DuDhhVND_ePmNkdYYQ2YsQZqVajtZQmZCjePeEag3oef08u2e8tvixjJEiWywCygUOOOxOMrGj4EiPgVtd8xeUnIyBDBlrXRfM9VKihdaDmb0g0WbMMDaAnWTmws4-\",\n\"parts\": [{\n\"partNumber\": 1,\n\"eTag\": \"a212be3df3b75034d3134181133961b0\"\n},\n{\n\"partNumber\": 2,\n\"eTag\": \"b1748f980effa301ef39a5b38cb1728e\"\n},\n{\n\"partNumber\": 3,\n\"eTag\": \"0812f72258be829e7c22094f69430e62\"\n}\n]\n}\n\n```\n\nThe /assemble endpoint will return with a success if it managed to assemble the chunks properly. e.g.\n\n``` json\n{\n\"result\": {\n\"status\": 0,\n\"message\": \"Success\"\n},\n\"data\": {\n\"uploadId\": \"KCTf7nos7bjhqk9w6y7wxXmQNsJWU1565Ul5bo.bfSfZM6DuDhhVND_ePmNkdYYQ2YsQZqVajtZQmZCjePeEag3oef08u2e8tvixjJEiWywCygUOOOxOMrGj4EiPgVtd8xeUnIyBDBlrXRfM9VKihdaDmb0g0WbMMDaAnWTmws4-\",\n\"asset\": \"example_client/assets/originals/0101/myLogo_010152_001.png\"\n}\n}\n\n```\n\nNow that the file has been reconstructed, it's now time to import the asset into the Brandworkz system.\n\n### 4\\. Import the assembled file\n\nThis is done in an identical manner to the single-file upload so see the corresponding section above for this.\n\n# Inserting asset metadata\n\nAfter having uploaded a new file via the API you may also want to add metadata to that new asset, which is done via the POST `/saveMetadata` endpoint.  \nYou can use this both for adding/modifying a number of fixed fields, as well as any custom metadata you may have set up in your instance of Brandworkz. This is done by posting json in the body/payload adhering to the following schema, where 'assetGuid' is the only mandatory field:\n\n``` json\n{\n  \"assetGuid\": \"string\",\n  \"assetPublishDate\": \"string\",\n  \"assetExpiryDate\": \"string\",\n  \"assetStatus\": 0,\n  \"assetTitle\": \"string\",\n  \"assetVersion\": 0,\n  \"languageCode\": \"string\",\n  \"metadata\": {},\n  \"metasetRef\": \"string\"\n}\n\n```\n\n## Inserting metadata to the fixed fields\n\nThese are the fixed fields:\n\n- **assetGuid** The asset's guid. Mandatory\n- **assetPublishDate** Set a publish date before which the asset will be unavailable. We recommend posting this in the **yyyy\\\\mm\\\\dd** format to avoid any ambiguity between US/non-US day/month notation.\n- **assetExpiryDate** Set an expiry date after which the asset will be unavailable. We recommend posting this in the **yyyy\\\\mm\\\\dd** format to avoid any ambiguity between US/non-US day/month notation.\n- **assetStatus**\n    - 0 - Set the asset to hidden. Only a system administrator can see it.\n    - 1 - This is the standard status; the asset can be viewed and download by any user with the correct permissions.\n    - 2 - View only. The asset can only be viewed, and not downloaded.\n- **assetTitle** Change the Title. Note that this can not be set to empty. Also note that if you try to set this to a title which is the same as another asset in the same folder you will get a 400 Bad Request response back, and a suggestion as to what you can rename it to in the `data.suggestion` node which will only be present if there is a name clash. The suggestion will be based on suffixing a number after the title asked for in the failing call.\n- **assetVersion** Ignore this. For potential future functionality. Asset metadata is currently not tied to a specific version of an asset but any/all versions.\n    \n\n## Inserting metadata to custom fields\n\nTo insert custom metadata you will need to use these parameters:\n\n- **assetGuid** The asset's guid\n- **languageCode** Only relevant if you have a multi-language system. This is for specifying the language code to insert to, where you need to call the endpoint separately for each of your langCodes. Note that you only need to do this for text entries, for multiple-choice entries only need to be saved in one language as they will then automatically be populated in all languages, assuming you have set up translations for the options.\n- **metasetRef** The systemRef for the metaset you are inserting values for. As a sysadmin or metadata admin you can see this by browsing to the relevant metaset in the admin area.\n- **metadata** A collection of fields specified by their systemRefs' and the associated values you want to insert.\n    \n\nAs an example, lets say we have a MetaSet for some product images which has a systemRef of `ASSETPRODUCTIMAGES`  \nThis metaset has the following fields in:\n\n| Friendly Name | SystemRef | Type | Options |\n| --- | --- | --- | --- |\n| Keywords | KEYWORDS | textarea | N/A |\n| SKU | SKU | Integer | N/A |\n| Shot angle | SHOTANGLE | Selectbox | Front/Left/Right |\n| Shot content | SHOTCONTENT | Checkbox | People/Object/Interior environment/Exterior environment |\n| Colour | COLOUR | Hierarchical | Red, Red->Burgundy, Red->Crimson, Green, Green->Avocado, Green->Lime green |\n\nIf we then had an asset with the following attributes:\n\n- The keywords we want to insert are: **boho chic, floral, spring**\n- It's SKU/product code is: **12364**\n- Its a shot from the **Front**\n- Its showing **people** and **Exterior environment**\n- It's **red** and **lime** coloured\n    \n\n...we would then post this Json in the body to insert that:\n\n``` json\n{\n   \"assetGuid\":\"2f0637c6-fd92-60c0-085b-154a2e3f263c\",\n   \"metasetRef\":\"ASSETPRODUCTIMAGES\",\n   \"metadata\":{\n      \"SKU\":\"12364\",\n      \"SHOTANGLE\":[\"Front\"],\n      \"THESHOTCONTENT\":[\"People\",\"Exterior environment\"],\n      \"COLOUR2\":[\"Red\",\"Green|Lime green\"\n      ],\n      \"KEYWORDS\":[\"boho chic, floral, spring\"]\n   }\n}\n\n```\n\nNote the following on the above:\n\n- **SKU/Number fields**. You should wrap these in double-quotes as is they were text fields\n- **SHOTANGLE/Single-option selectbox or radio button**: You can either pass the value as a single-item array as per above, or simply a text value. You must pass an option which exists for that field already, otherwise a 500 error will be returned\n- **Shot Content/multi-value fields** : You must pass this as an array of text entries. You must pass options which exist for that field already, otherwise a 500 error will be returned\n- **Colour/hierarchical fields** : You can target options at any level in the hierarchy but if the option isn't at the root, then you must pass a pipe-delimited path as per \"Green|Lime green\" above.\n- **Keywords/text and textarea fields**: You can either pass these as single-item array entries as per above or just a text value.\n    \n\nFinally, you can insert both fixed and custom metadata in the same call.\n\n# Error Handling\n\nThe API calls will respond with appropriate [HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for all requests. When a response is received, the status code is returned and is accompanied by a help text that indicates the possible meaning of the response code. A `200 OK` indicates all went well, while `4XX` or `5XX` response codes indicate an error from the requesting client or our API servers respectively.\n\nThe most common errors you can encounter in the Brandworkz API are as follows:\n\n| HTTP Status Code | Response Code | Error Message | Cause |\n| --- | --- | --- | --- |\n| 401 | 1 | Full authentication is required to access this resource | You are trying to access the API without authenticating. |\n| 502 | 2 | Service not available | You are trying to access a service that isn’t running. |\n| 422 | 3 | Argument error | Depending on endpoint. This is caused when parameters don’t pass validation. |\n| 500 | 4 | Configuration error | A configuration value could not get retrieved, thus the action could not be completed. |\n\n# Infrastructure\n\nThe approach we are implementing is a micro-services architecture. Unlike a monolithic or standalone API, our system has the ability to scale up as needed. Endpoints are grouped by service and below is a list of the key services relating to DAM:\n\n1. Albums\n2. Annotations\n3. Assets\n4. Categories\n5. CMS\n6. Integration\n7. Metadata\n8. Navigation\n9. Search\n10. Users\n    \n\n> Please contact Brandworkz to find out more about other API services relating to other Brandworkz modules (e.g. Workflow and Web-to-Print).\n\n# Responses\n\nThe response to every request is sent in JSON format by default. Some endpoints have the option for other formats, such as HTML. This can be specified passing the optional query parameter `format` or making use of the request header `Accept` when calling an endpoint. We also return a response message and code for every call to check if the operation was successful, independently of the resulting content, in the following way:\n\n``` json\n{\n\"result\": {\n// message and status code\n},\n\"data\": {\n// content\n}\n}\n\n```\n\nFor example:\n\n``` json\n{\n\"result\": {\n\"status\": 5,\n\"message\": \"Service endpoint call failed\"\n},\n\"data\": {\n\"dateTime\": \"2019-02-11T10:50:56.924\",\n\"rootCause\": \"Can't find a service with serviceId = cms-v1.6\",\n\"endpointName\": \"cms/templates\",\n\"method\": \"post\"\n}\n}\n\n```\n\n# Endpoint Structure\n\nWe work with several environments, so the versions and URLs change as the API evolves. The following three data variables are therefore essential when calling API endpoints:\n\n`api_url`: The API base URL that needs to be used for all subsequent endpoint calls.\n\n`client_id`: This is an identifier, specific for each client.\n\n`api_version`: The current API version.\n\n> **Important:** These values must be always set dynamically using the `getAPIURL` call and never be hard-coded. We ensure this way consistency and integrity with the API. Hard-coding these values should be considered a bad practice and it is prone to errors.\n\nThese data variables are used at the beginning of every endpoint as follows:\n\n`{{api_url}}/v{{api_version}}/{{client_id}}/endpoint`\n\n> **Tip:** For ease of use inside Postman, you could store the above as [environment variables](https://www.getpostman.com/docs/environments). Then always run the `/getAPIURL` followed by the `/oauth/token` call before making any other API calls. More info on setting up Postman variables can be found [here](https://developers.onelogin.com/api-docs/1/getting-started/postman-collections).","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"2016221","collectionId":"09cbeb08-240d-4650-acad-ae127896c96a","publishedId":"2s93RRwtCU","public":true,"publicUrl":"https://apidocs.brandworkz.com","privateUrl":"https://go.postman.co/documentation/2016221-09cbeb08-240d-4650-acad-ae127896c96a","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-double-column","customisation":null,"version":"8.10.0","publishDate":"2023-03-29T08:15:57.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/768118b36f06c94b0306958b980558e6915839447e859fe16906e29d683976f0","favicon":"https://brandworkz.com/favicon.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://apidocs.brandworkz.com/view/metadata/2s93RRwtCU"}