Skip to content
← Back to Functions
Code

API Response Normalizer

Normalizes different API response shapes into status, headers, body, error, and timing fields.

Function signature

ogNormalizeApiResponse(response = array(), options = array())

Categories

  • Security

Parameters

responseRaw response data with status_code, headers, body, error, and duration_ms keys. Recognized keys: `body`, `code`, `duration_ms`, `error`, `headers`, `status_code`.optionsNormalization options.

Return value

Short public-safe status message.

  • ok
  • status_code
  • headers
  • body
  • json_valid
  • json
  • error
  • duration_ms

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, policy arrays, URLs, signatures, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Normalizes an HTTP/API response into a consistent structure.
 *
 * The helper accepts common response shapes while preserving the raw body for
 * server-side diagnostics and exposing decoded JSON only when valid.
 *
 * @param array $response Raw response data with status_code, headers, body, error, and duration_ms keys.
 * @param array $options Normalization options.
 * @return array Normalized API response data.
 */
function ogNormalizeApiResponse($response = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($response)) {
		$result['message'] = 'Response must be an array.';
		return $result;
	}

	if (!is_array($options)) {
		$options = array();
	}

	$status_code = 0;
	if (!empty($response['status_code'])) {
		$status_code = (int)$response['status_code'];
	} elseif (!empty($response['code'])) {
		$status_code = (int)$response['code'];
	}

	$headers = array();
	if (!empty($response['headers']) && is_array($response['headers'])) {
		foreach ($response['headers'] as $key => $value) {
			$header_key = strtolower(trim((string)$key));
			if (!empty($header_key)) {
				$headers[$header_key] = trim((string)$value);
			}
		}
	}

	$body = '';
	if (array_key_exists('body', $response)) {
		$body = (string)$response['body'];
	}

	$error = '';
	if (!empty($response['error'])) {
		$error = trim((string)$response['error']);
	}

	$decoded_json = array();
	$json_valid = false;
	$content_type = '';
	if (!empty($headers['content-type'])) {
		$content_type = $headers['content-type'];
	}
	if (!empty($body) && strpos(strtolower($content_type), 'json') !== false) {
		$decoded = json_decode($body, true);
		if (json_last_error() == JSON_ERROR_NONE && is_array($decoded)) {
			$decoded_json = $decoded;
			$json_valid = true;
		}
	}

	$ok = false;
	if ($status_code >= 200 && $status_code < 300 && empty($error)) {
		$ok = true;
	}

	$duration_ms = 0;
	if (!empty($response['duration_ms'])) {
		$duration_ms = (int)$response['duration_ms'];
	}

	$result['success'] = true;
	$result['message'] = 'API response normalized.';
	$result['data'] = array(
		'ok' => $ok,
		'status_code' => $status_code,
		'headers' => $headers,
		'body' => $body,
		'json_valid' => $json_valid,
		'json' => $decoded_json,
		'error' => $error,
		'duration_ms' => $duration_ms
	);

	return $result;
}