public static function createFromString(string $json): self
    {
        $data = guzzle_json_decode($json, true);

        if (
            !isset($data['api']) ||
            !isset($data['request']) ||
            !isset($data['response']) ||
            !isset($data['duration']) ||
            !isset($data['exception'])
        ) {
            throw new \InvalidArgumentException(
                'String passed to Message::createFromString() is valid JSON but does not contain required fields.'
            );
        }

        return new self(
            $data['api'],
            $data['duration'],
            guzzle_parse_request($data['request']),
            $data['response'] ? guzzle_parse_response($data['response']) : null,
            $data['exception'] ? \unserialize($data['exception']) : null
        );
    }