HTTP.Post
Core library HTTP POST — posts a payload and returns an object with StatusCode and Response. Requires Platform.Load.
HTTP.Post sends a POST with the given content type and body. It returns an object with two fields: StatusCode (the HTTP status as a number) and Response (an array whose first element Response[0] is the response body string).
Requires Platform.Load("core", "1.1.5") before use.
Syntax
var response = HTTP.Post(url, contentType, payload[, headerNames, headerValues]);
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Syntax - HTTP.Post(url, contentType, payload[, headerNames, headerValues]).
*
* Proves:
* 1. The Core load requirement: after Platform.Load("core", "1.1.5") the
* bare global HTTP is bound and HTTP.Post is callable.
* 2. The 3-argument form works: url, contentType and payload alone, with
* NOTHING passed after payload, returns a usable response object.
* 3. The 5-argument form works: headerNames and headerValues supplied as
* two parallel arrays after payload.
* 4. Both documented forms carry the SAME numeric StatusCode for the same
* endpoint, so supplying headers does not change the documented call
* result.
*
* SCOPE: evidence gathered on a CloudPage GET only; the assertions depend on
* the external endpoint https://postman-echo.com/post being reachable from
* the SFMC egress and accepting a POST body.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertSyn(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function typeOfSyn(thunk) {
try { return thunk(); } catch (ex) { return "threw: " + ("" + ex.message); }
}
var SYN_URL = "https://postman-echo.com/post";
var SYN_BODY = "{\"event\":\"form_submit\"}";
/* 1. Core load makes the bare HTTP global available. */
assertSyn("after Platform.Load(core,1.1.5) HTTP is an object", typeOfSyn(function () { return typeof HTTP; }), "object");
assertSyn("HTTP.Post is callable", typeOfSyn(function () { return typeof HTTP.Post; }), "function");
/* 2. The 3-argument form - nothing passed after payload. */
var synPlain = HTTP.Post(SYN_URL, "application/json", SYN_BODY);
assertSyn("HTTP.Post(url, contentType, payload) returns an object", typeof synPlain, "object");
assertSyn("the 3-argument form yields a numeric StatusCode", typeof synPlain.StatusCode, "number");
/* 3. The 5-argument form - parallel header arrays after payload. */
var synHdr = HTTP.Post(SYN_URL, "application/json", SYN_BODY, ["X-API-Key"], ["mysecretkey"]);
assertSyn("HTTP.Post(url, contentType, payload, headerNames, headerValues) returns an object", typeof synHdr, "object");
assertSyn("the 5-argument form yields a numeric StatusCode", typeof synHdr.StatusCode, "number");
/* 4. Both documented forms agree on the status. */
assertSyn("both documented forms return the same StatusCode", synHdr.StatusCode === synPlain.StatusCode ? "true" : "false", "true");
</script>
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Target URL |
contentType |
string | Yes | MIME type of the request body |
payload |
string | Yes | Request body string |
headerNames |
string[] | No | Header names (co-required with headerValues) |
headerValues |
string[] | No | Values paired with headerNames (co-required) |
The official docs list headerNames and headerValues as required, but the runtime accepts a 3-argument call (url, contentType, payload); the two header arrays are optional and only need to be paired when supplied.
Show test script — optional header arrays
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* differs-from-docs (Parameters): the official docs list headerNames and
* headerValues as REQUIRED, but the runtime accepts a 3-argument call.
*
* Proves:
* 1. DEV - the 3-argument call HTTP.Post(url, contentType, payload)
* succeeds and returns an object (official docs: headerNames and
* headerValues are required, so this call should not be valid).
* 2. DEV - that 3-argument call produces a real numeric StatusCode, i.e.
* the request was actually issued, not silently ignored.
* 3. The header arrays only need to be PAIRED when supplied: a supplied
* pair of equal length works too, so the arrays are optional rather
* than ignored.
*
* SCOPE: evidence gathered on a CloudPage GET only; the assertions depend on
* the external endpoint https://postman-echo.com/post being reachable from
* the SFMC egress.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertOpt(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
var OPT_URL = "https://postman-echo.com/post";
var OPT_BODY = "{\"event\":\"form_submit\"}";
/* 1. + 2. The undocumented-but-working 3-argument form. */
var optPlain = HTTP.Post(OPT_URL, "application/json", OPT_BODY);
assertOpt("DEV the 3-argument call returns an object (official docs: headerNames/headerValues required)", typeof optPlain, "object");
assertOpt("DEV the 3-argument call really issued the request - numeric StatusCode (official docs: call should require 5 arguments)", typeof optPlain.StatusCode, "number");
/* 3. Supplying a paired set works as well - the arrays are optional, not ignored. */
var optHdr = HTTP.Post(OPT_URL, "application/json", OPT_BODY, ["X-API-Key"], ["mysecretkey"]);
assertOpt("a supplied equal-length header pair is also accepted", typeof optHdr.StatusCode, "number");
</script>
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Parameters - url (string, required), contentType (string,
* required), payload (string, required), headerNames (string[], optional,
* co-required with headerValues), headerValues (string[], optional,
* co-required).
*
* Proves:
* 1. url, contentType and payload are accepted as strings and together
* produce a response object with a numeric StatusCode.
* 2. payload really is the REQUEST BODY: the echo endpoint reflects the
* posted string back, so the payload argument reached the server.
* 3. contentType really is the MIME type of the request body: the echo
* endpoint reports the content-type header we passed.
* 4. headerNames / headerValues are OPTIONAL - the 3-argument form
* succeeds without them (also covered in the Syntax chapter).
* 5. headerNames / headerValues are string ARRAYS and are PAIRED: the
* value supplied in headerValues is sent under the name supplied in
* headerNames, proven by the echo endpoint reflecting the header value.
*
* NOT ASSERTABLE: that MISMATCHED headerNames / headerValues lengths are
* rejected. The page states the arrays are co-required and "only need to be
* paired when supplied" as a CALLER requirement, not as a documented runtime
* error contract, so there is no documented outcome to assert.
*
* TYPE-ACCEPTANCE MATRIX: no parameter on this page is in scope. `url` is a
* URL string and `contentType` a MIME-type string (both explicitly excluded
* from widening), `payload` is a free-text request-body string, and
* headerNames / headerValues are string ARRAYS, not scalars - none matches a
* Date/Number/Boolean/string pair.
*
* SCOPE: evidence gathered on a CloudPage GET only; the assertions depend on
* the external endpoint https://postman-echo.com/post being reachable from
* the SFMC egress and echoing the request.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertPar(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
var PAR_URL = "https://postman-echo.com/post";
var PAR_BODY = "{\"event\":\"form_submit\"}";
/* 1. + 4. All three required strings, headers omitted. */
var parRes = HTTP.Post(PAR_URL, "application/json", PAR_BODY);
assertPar("url + contentType + payload as strings return an object", typeof parRes, "object");
assertPar("headerNames and headerValues are optional (3-argument form works)", typeof parRes.StatusCode, "number");
/* 2. payload is the request body - echoed back by the endpoint. */
var parEcho = "" + parRes.Response[0];
assertPar("payload is sent as the request body (echoed back)", parEcho.indexOf("form_submit") >= 0 ? "true" : "false", "true");
/* 3. contentType is the MIME type of the request body. */
assertPar("contentType is sent as the request content type", parEcho.indexOf("application/json") >= 0 ? "true" : "false", "true");
/* 5. headerNames / headerValues are paired string arrays. */
var parHdr = HTTP.Post(PAR_URL, "application/json", PAR_BODY, ["X-API-Key"], ["mysecretkey"]);
assertPar("a paired string[] header pair is accepted", typeof parHdr.StatusCode, "number");
var parHdrEcho = "" + parHdr.Response[0];
assertPar("the headerValues entry is sent under its headerNames entry", parHdrEcho.indexOf("mysecretkey") >= 0 ? "true" : "false", "true");
</script>
Return value
Returns an object (not a bare string) with these fields:
| Field | Type | Description |
|---|---|---|
StatusCode |
number | HTTP status code of the response |
Response |
string[] | Array whose first element Response[0] is the response body |
The official docs type StatusCode as a string and Response as a single string, but the runtime returns StatusCode as a number and Response as an array whose first element (Response[0]) holds the body.
Show test script — StatusCode/Response runtime shape
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* differs-from-docs (Return value): the official docs type StatusCode as a
* STRING and Response as a SINGLE STRING, but the runtime returns a numeric
* StatusCode and an ARRAY whose first element holds the body.
*
* Proves:
* 1. DEV - StatusCode is a number (official docs: string).
* 2. DEV - StatusCode is NOT a string (official docs: string).
* 3. DEV - Response is not a string but an array-like object
* (official docs: a single string).
* 4. DEV - the body is reached through Response[0], not through Response
* itself (official docs: Response IS the body string).
*
* SCOPE: evidence gathered on a CloudPage GET only; the assertions depend on
* the external endpoint https://postman-echo.com/post being reachable from
* the SFMC egress.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertShape(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
var SHAPE_URL = "https://postman-echo.com/post";
var shape = HTTP.Post(SHAPE_URL, "application/json", "{\"event\":\"form_submit\"}");
/* 1. + 2. StatusCode is numeric, not a string. */
assertShape("DEV StatusCode is a number (official docs: string)", typeof shape.StatusCode, "number");
assertShape("DEV StatusCode is NOT a string (official docs: string)", typeof shape.StatusCode === "string" ? "true" : "false", "false");
/* 3. Response is array-like, not a string. */
assertShape("DEV Response is NOT a string (official docs: a single string)", typeof shape.Response === "string" ? "true" : "false", "false");
assertShape("DEV Response has a numeric length, i.e. it is an array (official docs: a single string)", typeof shape.Response.length, "number");
/* 4. The body lives at Response[0]. */
assertShape("DEV the body is at Response[0] (official docs: Response itself is the body)", typeof shape.Response[0], "string");
assertShape("DEV Response[0] holds the actual response body (official docs: Response itself is the body)", ("" + shape.Response[0]).indexOf("form_submit") >= 0 ? "true" : "false", "true");
</script>
Note that HTTP.Post uses different field names than HTTP.Get, which returns { Status, Content }.
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Return value - an OBJECT with StatusCode (number) and Response
* (string[] whose first element is the body).
*
* Proves:
* 1. The return value is an object, not a bare string.
* 2. StatusCode is a NUMBER carrying the HTTP status code.
* 3. Response is an ARRAY, not a bare string.
* 4. Response[0] is a string holding the response body, and it is
* non-empty for a reachable endpoint.
* 5. The field names really are StatusCode / Response and NOT the HTTP.Get
* pair Status / Content - the page's note that the two members use
* different field names is proven by Status and Content being absent
* on the HTTP.Post result.
*
* SCOPE: evidence gathered on a CloudPage GET only; the assertions depend on
* the external endpoint https://postman-echo.com/post being reachable from
* the SFMC egress.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertRv(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
var RV_URL = "https://postman-echo.com/post";
var rv = HTTP.Post(RV_URL, "application/json", "{\"event\":\"form_submit\"}");
/* 1. An object, not a bare string. */
assertRv("the return value is an object", typeof rv, "object");
assertRv("the return value is NOT a string", typeof rv === "string" ? "true" : "false", "false");
/* 2. StatusCode is the numeric HTTP status. */
assertRv("StatusCode is a number", typeof rv.StatusCode, "number");
assertRv("StatusCode carries the HTTP status code of the response", rv.StatusCode === 200 ? "true" : "false", "true");
/* 3. + 4. Response is an array whose first element is the body. */
assertRv("Response is an object (an array), not a bare string", typeof rv.Response, "object");
assertRv("Response has a numeric length, i.e. it is array-like", typeof rv.Response.length, "number");
assertRv("Response[0] is a string", typeof rv.Response[0], "string");
assertRv("Response[0] is non-empty for a reachable endpoint", ("" + rv.Response[0]).length > 0 ? "true" : "false", "true");
/* 5. Not the HTTP.Get field names. */
assertRv("Status (the HTTP.Get name) is undefined here", typeof rv.Status, "undefined");
assertRv("Content (the HTTP.Get name) is undefined here", typeof rv.Content, "undefined");
</script>
Example
Platform.Load("core", "1.1.5");
var payload = Stringify({
event: "form_submit",
email: submitterEmail,
timestamp: Platform.Function.Now()
});
var response = HTTP.Post(
"https://api.example.com/events",
"application/json",
payload,
["X-API-Key"],
["mysecretkey"]
);
if (response.StatusCode == 200) {
var result = Platform.Function.ParseJSON(String(response.Response[0]));
}
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");
/*
* Chapter: Example - the documented snippet, line by line.
*
* Proves:
* 1. Stringify({...}) with a Platform.Function.Now() member produces the
* payload string the example builds.
* 2. var response = HTTP.Post(url, contentType, payload, headerNames,
* headerValues) - the exact 5-argument documented call - returns an
* object.
* 3. The documented guard `response.StatusCode == 200` evaluates true for
* a successful call, i.e. the numeric StatusCode compares against the
* literal 200 as written.
* 4. Platform.Function.ParseJSON(String(response.Response[0])) - the exact
* documented parse line, including the String(...) wrapper - yields a
* non-null object.
*
* SCOPE: evidence gathered on a CloudPage GET only. The example's
* api.example.com URL is a placeholder and is NOT contacted; the stable
* public echo endpoint https://postman-echo.com/post is used instead, so
* these assertions depend on it being reachable from the SFMC egress.
*
* EXPECTED OUTPUT: every line starts with PASS.
*/
function assertEx(id, actual, expected) {
Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
var EX_URL = "https://postman-echo.com/post";
var submitterEmail = "test@example.com";
/* 1. The payload the example builds. */
var payload = Stringify({
event: "form_submit",
email: submitterEmail,
timestamp: Platform.Function.Now()
});
assertEx("Stringify({...}) builds a string payload", typeof payload, "string");
assertEx("the payload carries the event value", ("" + payload).indexOf("form_submit") >= 0 ? "true" : "false", "true");
/* 2. The documented 5-argument call. */
var response = HTTP.Post(
EX_URL,
"application/json",
payload,
["X-API-Key"],
["mysecretkey"]
);
assertEx("var response = HTTP.Post(url, contentType, payload, headerNames, headerValues) returns an object", typeof response, "object");
/* 3. The documented status guard. */
assertEx("response.StatusCode == 200 holds for a successful call", response.StatusCode == 200 ? "true" : "false", "true");
/* 4. The documented parse line. */
var result = Platform.Function.ParseJSON(String(response.Response[0]));
assertEx("ParseJSON(String(response.Response[0])) yields an object", typeof result, "object");
assertEx("the parsed value is not null", result === null ? "true" : "false", "false");
</script>