### Code generated by codegen/main.go. DO NOT EDIT. ###

extends RefCounted
class_name SatoriAPI

# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
class ApiAuthenticateLogoutRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}
	
	# Refresh token to invalidate.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)
	
	# Session token to log out.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateLogoutRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateLogoutRequest", p_dict), ApiAuthenticateLogoutRequest) as ApiAuthenticateLogoutRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		output += map_string
		return output

# Authenticate against the server with a refresh token.
class ApiAuthenticateRefreshRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
	}
	
	# Refresh token.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRefreshRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRefreshRequest", p_dict), ApiAuthenticateRefreshRequest) as ApiAuthenticateRefreshRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "refresh_token: %s, " % _refresh_token
		output += map_string
		return output

# 
class ApiAuthenticateRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
	}
	
	# Optional custom properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Optional default properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Identity ID. Must be between eight and 128 characters (inclusive).
	# Must be an alphanumeric string with only underscores and hyphens allowed.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAuthenticateRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiAuthenticateRequest", p_dict), ApiAuthenticateRequest) as ApiAuthenticateRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "id: %s, " % _id
		output += map_string
		return output

# A single event. Usually, but not necessarily, part of a batch.
class ApiEvent extends SatoriAsyncResult:

	const _SCHEMA = {
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# Optional event ID assigned by the client, used to de-duplicate in retransmission scenarios.
	# If not supplied the server will assign a randomly generated unique event identifier.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)
	
	# Event metadata, if any.
	var _metadata
	var metadata : Dictionary:
		get:
			return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
	
	# Event name.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# The time when the event was triggered on the producer side.
	var _timestamp
	var timestamp : String:
		get:
			return "" if not _timestamp is String else String(_timestamp)
	
	# Optional value.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "id: %s, " % _id
		if typeof(_metadata) == TYPE_DICTIONARY:
			for k in _metadata:
				map_string += "{%s=%s}, " % [k, _metadata[k]]
		output += "metadata: [%s], " % map_string
		map_string = ""
		output += "name: %s, " % _name
		output += "timestamp: %s, " % _timestamp
		output += "value: %s, " % _value
		output += map_string
		return output

# 
class ApiEventRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"events": {"name": "_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# Some number of events produced by a client.
	var _events
	var events : Array:
		get:
			return Array() if not _events is Array else Array(_events)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEventRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiEventRequest", p_dict), ApiEventRequest) as ApiEventRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "events: %s, " % [_events]
		output += map_string
		return output

# An experiment that this user is partaking.
class ApiExperiment extends SatoriAsyncResult:

	const _SCHEMA = {
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Value associated with this Experiment.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperiment:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperiment", p_dict), ApiExperiment) as ApiExperiment

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# All experiments that this identity is involved with.
class ApiExperimentList extends SatoriAsyncResult:

	const _SCHEMA = {
		"experiments": {"name": "_experiments", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# All experiments for this identity.
	var _experiments
	var experiments : Array:
		get:
			return Array() if not _experiments is Array else Array(_experiments)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiExperimentList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiExperimentList", p_dict), ApiExperimentList) as ApiExperimentList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "experiments: %s, " % [_experiments]
		output += map_string
		return output

# Feature flag available to the identity.
class ApiFlag extends SatoriAsyncResult:

	const _SCHEMA = {
		"condition_changed": {"name": "_condition_changed", "type": TYPE_BOOL, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# Whether the value for this flag has conditionally changed from the default state.
	var _condition_changed
	var condition_changed : bool:
		get:
			return false if not _condition_changed is bool else bool(_condition_changed)
	
	# 
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Value associated with this flag.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlag:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlag", p_dict), ApiFlag) as ApiFlag

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "condition_changed: %s, " % _condition_changed
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# 
class ApiFlagList extends SatoriAsyncResult:

	const _SCHEMA = {
		"flags": {"name": "_flags", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# 
	var _flags
	var flags : Array:
		get:
			return Array() if not _flags is Array else Array(_flags)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFlagList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiFlagList", p_dict), ApiFlagList) as ApiFlagList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "flags: %s, " % [_flags]
		output += map_string
		return output

# A response containing all the messages for an identity.
class ApiGetMessageListResponse extends SatoriAsyncResult:

	const _SCHEMA = {
		"cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false},
		"messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
		"next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false},
		"prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false},
	}
	
	# Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
	var _cacheable_cursor
	var cacheable_cursor : String:
		get:
			return "" if not _cacheable_cursor is String else String(_cacheable_cursor)
	
	# The list of messages.
	var _messages
	var messages : Array:
		get:
			return Array() if not _messages is Array else Array(_messages)
	
	# The cursor to send when retrieving the next page, if any.
	var _next_cursor
	var next_cursor : String:
		get:
			return "" if not _next_cursor is String else String(_next_cursor)
	
	# The cursor to send when retrieving the previous page, if any.
	var _prev_cursor
	var prev_cursor : String:
		get:
			return "" if not _prev_cursor is String else String(_prev_cursor)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGetMessageListResponse:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiGetMessageListResponse", p_dict), ApiGetMessageListResponse) as ApiGetMessageListResponse

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "cacheable_cursor: %s, " % _cacheable_cursor
		output += "messages: %s, " % [_messages]
		output += "next_cursor: %s, " % _next_cursor
		output += "prev_cursor: %s, " % _prev_cursor
		output += map_string
		return output

# Enrich/replace the current session with a new ID.
class ApiIdentifyRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
	}
	
	# Optional custom properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Optional default properties to update with this call.
	# If not set, properties are left as they are on the server.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Identity ID to enrich the current session and return a new session. Old session will no longer be usable.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiIdentifyRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiIdentifyRequest", p_dict), ApiIdentifyRequest) as ApiIdentifyRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "id: %s, " % _id
		output += map_string
		return output

# A single live event.
class ApiLiveEvent extends SatoriAsyncResult:

	const _SCHEMA = {
		"active_end_time_sec": {"name": "_active_end_time_sec", "type": TYPE_STRING, "required": false},
		"active_start_time_sec": {"name": "_active_start_time_sec", "type": TYPE_STRING, "required": false},
		"description": {"name": "_description", "type": TYPE_STRING, "required": false},
		"id": {"name": "_id", "type": TYPE_STRING, "required": false},
		"name": {"name": "_name", "type": TYPE_STRING, "required": false},
		"value": {"name": "_value", "type": TYPE_STRING, "required": false},
	}
	
	# End time of current event run.
	var _active_end_time_sec
	var active_end_time_sec : String:
		get:
			return "" if not _active_end_time_sec is String else String(_active_end_time_sec)
	
	# Start time of current event run.
	var _active_start_time_sec
	var active_start_time_sec : String:
		get:
			return "" if not _active_start_time_sec is String else String(_active_start_time_sec)
	
	# Description.
	var _description
	var description : String:
		get:
			return "" if not _description is String else String(_description)
	
	# The live event identifier.
	var _id
	var id : String:
		get:
			return "" if not _id is String else String(_id)
	
	# Name.
	var _name
	var name : String:
		get:
			return "" if not _name is String else String(_name)
	
	# Event value.
	var _value
	var value : String:
		get:
			return "" if not _value is String else String(_value)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEvent:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEvent", p_dict), ApiLiveEvent) as ApiLiveEvent

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "active_end_time_sec: %s, " % _active_end_time_sec
		output += "active_start_time_sec: %s, " % _active_start_time_sec
		output += "description: %s, " % _description
		output += "id: %s, " % _id
		output += "name: %s, " % _name
		output += "value: %s, " % _value
		output += map_string
		return output

# List of Live events.
class ApiLiveEventList extends SatoriAsyncResult:

	const _SCHEMA = {
		"live_events": {"name": "_live_events", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
	}
	
	# Live events.
	var _live_events
	var live_events : Array:
		get:
			return Array() if not _live_events is Array else Array(_live_events)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLiveEventList:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiLiveEventList", p_dict), ApiLiveEventList) as ApiLiveEventList

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "live_events: %s, " % [_live_events]
		output += map_string
		return output

# A scheduled message.
class ApiMessage extends SatoriAsyncResult:

	const _SCHEMA = {
		"consume_time": {"name": "_consume_time", "type": TYPE_STRING, "required": false},
		"create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false},
		"metadata": {"name": "_metadata", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"read_time": {"name": "_read_time", "type": TYPE_STRING, "required": false},
		"schedule_id": {"name": "_schedule_id", "type": TYPE_STRING, "required": false},
		"send_time": {"name": "_send_time", "type": TYPE_STRING, "required": false},
		"text": {"name": "_text", "type": TYPE_STRING, "required": false},
		"update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false},
	}
	
	# The time the message was consumed by the identity.
	var _consume_time
	var consume_time : String:
		get:
			return "" if not _consume_time is String else String(_consume_time)
	
	# The time the message was created.
	var _create_time
	var create_time : String:
		get:
			return "" if not _create_time is String else String(_create_time)
	
	# A key-value pairs of metadata.
	var _metadata
	var metadata : Dictionary:
		get:
			return Dictionary() if not _metadata is Dictionary else _metadata.duplicate()
	
	# The time the message was read by the client.
	var _read_time
	var read_time : String:
		get:
			return "" if not _read_time is String else String(_read_time)
	
	# The identifier of the schedule.
	var _schedule_id
	var schedule_id : String:
		get:
			return "" if not _schedule_id is String else String(_schedule_id)
	
	# The send time for the message.
	var _send_time
	var send_time : String:
		get:
			return "" if not _send_time is String else String(_send_time)
	
	# The message's text.
	var _text
	var text : String:
		get:
			return "" if not _text is String else String(_text)
	
	# The time the message was updated.
	var _update_time
	var update_time : String:
		get:
			return "" if not _update_time is String else String(_update_time)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMessage:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiMessage", p_dict), ApiMessage) as ApiMessage

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "consume_time: %s, " % _consume_time
		output += "create_time: %s, " % _create_time
		if typeof(_metadata) == TYPE_DICTIONARY:
			for k in _metadata:
				map_string += "{%s=%s}, " % [k, _metadata[k]]
		output += "metadata: [%s], " % map_string
		map_string = ""
		output += "read_time: %s, " % _read_time
		output += "schedule_id: %s, " % _schedule_id
		output += "send_time: %s, " % _send_time
		output += "text: %s, " % _text
		output += "update_time: %s, " % _update_time
		output += map_string
		return output

# Properties associated with an identity.
class ApiProperties extends SatoriAsyncResult:

	const _SCHEMA = {
		"computed": {"name": "_computed", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
	}
	
	# Event computed properties.
	var _computed
	var computed : Dictionary:
		get:
			return Dictionary() if not _computed is Dictionary else _computed.duplicate()
	
	# Event custom properties.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Event default properties.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiProperties:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiProperties", p_dict), ApiProperties) as ApiProperties

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_computed) == TYPE_DICTIONARY:
			for k in _computed:
				map_string += "{%s=%s}, " % [k, _computed[k]]
		output += "computed: [%s], " % map_string
		map_string = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += map_string
		return output

# A session.
class ApiSession extends SatoriAsyncResult:

	const _SCHEMA = {
		"properties": {"name": "_properties", "type": "ApiProperties", "required": false},
		"refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false},
		"token": {"name": "_token", "type": TYPE_STRING, "required": false},
	}
	
	# Properties associated with this identity.
	var _properties
	var properties : ApiProperties:
		get:
			return _properties as ApiProperties
	
	# Refresh token.
	var _refresh_token
	var refresh_token : String:
		get:
			return "" if not _refresh_token is String else String(_refresh_token)
	
	# Token credential.
	var _token
	var token : String:
		get:
			return "" if not _token is String else String(_token)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "properties: %s, " % _properties
		output += "refresh_token: %s, " % _refresh_token
		output += "token: %s, " % _token
		output += map_string
		return output

# Update Properties associated with this identity.
class ApiUpdatePropertiesRequest extends SatoriAsyncResult:

	const _SCHEMA = {
		"custom": {"name": "_custom", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"default": {"name": "_default", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING},
		"recompute": {"name": "_recompute", "type": TYPE_BOOL, "required": false},
	}
	
	# Event custom properties.
	var _custom
	var custom : Dictionary:
		get:
			return Dictionary() if not _custom is Dictionary else _custom.duplicate()
	
	# Event default properties.
	var _default
	var default : Dictionary:
		get:
			return Dictionary() if not _default is Dictionary else _default.duplicate()
	
	# Informs the server to recompute the audience membership of the identity.
	var _recompute
	var recompute : bool:
		get:
			return false if not _recompute is bool else bool(_recompute)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdatePropertiesRequest:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ApiUpdatePropertiesRequest", p_dict), ApiUpdatePropertiesRequest) as ApiUpdatePropertiesRequest

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		if typeof(_custom) == TYPE_DICTIONARY:
			for k in _custom:
				map_string += "{%s=%s}, " % [k, _custom[k]]
		output += "custom: [%s], " % map_string
		map_string = ""
		if typeof(_default) == TYPE_DICTIONARY:
			for k in _default:
				map_string += "{%s=%s}, " % [k, _default[k]]
		output += "default: [%s], " % map_string
		map_string = ""
		output += "recompute: %s, " % _recompute
		output += map_string
		return output

# 
class ProtobufAny extends SatoriAsyncResult:

	const _SCHEMA = {
		"type": {"name": "_type", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _type
	var type : String:
		get:
			return "" if not _type is String else String(_type)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> ProtobufAny:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "ProtobufAny", p_dict), ProtobufAny) as ProtobufAny

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "type: %s, " % _type
		output += map_string
		return output

# 
class RpcStatus extends SatoriAsyncResult:

	const _SCHEMA = {
		"code": {"name": "_code", "type": TYPE_INT, "required": false},
		"details": {"name": "_details", "type": TYPE_ARRAY, "required": false, "content": TYPE_DICTIONARY},
		"message": {"name": "_message", "type": TYPE_STRING, "required": false},
	}
	
	# 
	var _code
	var code : int:
		get:
			return 0 if not _code is int else int(_code)
	
	# 
	var _details
	var details : Array:
		get:
			return Array() if not _details is Array else Array(_details)
	
	# 
	var _message
	var message : String:
		get:
			return "" if not _message is String else String(_message)

	func _init(p_exception = null):
		super(p_exception)

	static func create(p_ns : GDScript, p_dict : Dictionary) -> RpcStatus:
		return _safe_ret(SatoriSerializer.deserialize(p_ns, "RpcStatus", p_dict), RpcStatus) as RpcStatus

	func serialize() -> Dictionary:
		return SatoriSerializer.serialize(self)

	func _to_string() -> String:
		if is_exception():
			return get_exception()._to_string()
		var output : String = ""
		var map_string : String = ""
		output += "code: %s, " % _code
		output += "details: %s, " % [_details]
		output += "message: %s, " % _message
		output += map_string
		return output

# The low level client for the Satori API.
class ApiClient extends RefCounted:

	var _base_uri : String

	var _http_adapter
	var _namespace : GDScript
	var _server_key : String
	var auto_refresh := true
	var auto_refresh_time := 300

	var auto_retry : bool:
		set(p_value):
			_http_adapter.auto_retry = p_value
		get:
			return _http_adapter.auto_retry

	var auto_retry_count : int:
		set(p_value):
			_http_adapter.auto_retry_count = p_value
		get:
			return _http_adapter.auto_retry_count

	var auto_retry_backoff_base : int:
		set(p_value):
			_http_adapter.auto_retry_backoff_base = p_value
		get:
			return _http_adapter.auto_retry_backoff_base

	var last_cancel_token:
		get:
			return _http_adapter.get_last_token()

	func _init(p_base_uri : String, p_http_adapter, p_namespace : GDScript, p_server_key : String, p_timeout : int = 10):
		_base_uri = p_base_uri
		_http_adapter = p_http_adapter
		_http_adapter.timeout = p_timeout
		_namespace = p_namespace
		_server_key = p_server_key

		
	func _refresh_session(p_session : SatoriSession):
		if auto_refresh and p_session.is_valid() and p_session.refresh_token and not p_session.is_refresh_expired() and p_session.would_expire_in(auto_refresh_time):
			var request = ApiAuthenticateRefreshRequest.new()
			request._token = p_session.refresh_token
			return await authenticate_refresh_async(_server_key, "", request)
		return null

	func cancel_request(p_token):
		if p_token:
			_http_adapter.cancel_request(p_token)

	# A healthcheck which load balancers can use to check the service.
	func healthcheck_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/healthcheck"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# A readycheck which load balancers can use to check the service.
	func readycheck_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/readycheck"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Authenticate against the server.
	func authenticate_async(
		p_basic_auth_username : String
		, p_basic_auth_password : String
		, p_body : ApiAuthenticateRequest
	) -> ApiSession:
		var urlpath : String = "/v1/authenticate"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
		var header = "Basic %s" % credentials
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
	func authenticate_logout_async(
		p_session : SatoriSession
		, p_body : ApiAuthenticateLogoutRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/authenticate/logout"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Refresh a user's session using a refresh token retrieved from a previous authentication request.
	func authenticate_refresh_async(
		p_basic_auth_username : String
		, p_basic_auth_password : String
		, p_body : ApiAuthenticateRefreshRequest
	) -> ApiSession:
		var urlpath : String = "/v1/authenticate/refresh"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password)
		var header = "Basic %s" % credentials
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Publish an event for this session.
	func event_async(
		p_session : SatoriSession
		, p_body : ApiEventRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/event"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "POST"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Get or list all available experiments for this identity.
	func get_experiments_async(
		p_session : SatoriSession
		, p_names = null # : array
	) -> ApiExperimentList:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiExperimentList.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/experiment"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiExperimentList.new(result)
		var out : ApiExperimentList = SatoriSerializer.deserialize(_namespace, "ApiExperimentList", result)
		return out

	# List all available flags for this identity.
	func get_flags_async(
		p_bearer_token : String
		, p_names = null # : array
	) -> ApiFlagList:
		var urlpath : String = "/v1/flag"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		if (p_bearer_token):
			var header = "Bearer %s" % p_bearer_token
			headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiFlagList.new(result)
		var out : ApiFlagList = SatoriSerializer.deserialize(_namespace, "ApiFlagList", result)
		return out

	# Enrich/replace the current session with new identifier.
	func identify_async(
		p_session : SatoriSession
		, p_body : ApiIdentifyRequest
	) -> ApiSession:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiSession.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/identify"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiSession.new(result)
		var out : ApiSession = SatoriSerializer.deserialize(_namespace, "ApiSession", result)
		return out

	# Delete the caller's identity and associated data.
	func delete_identity_async(
		p_session : SatoriSession
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/identity"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "DELETE"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# List available live events.
	func get_live_events_async(
		p_session : SatoriSession
		, p_names = null # : array
	) -> ApiLiveEventList:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiLiveEventList.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/live-event"
		var query_params = ""
		if p_names != null:
			for elem in p_names:
				query_params += "names=%s&" % elem
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiLiveEventList.new(result)
		var out : ApiLiveEventList = SatoriSerializer.deserialize(_namespace, "ApiLiveEventList", result)
		return out

	# Get the list of messages for the identity.
	func get_message_list_async(
		p_session : SatoriSession
		, p_limit = null # : integer
		, p_forward = null # : boolean
		, p_cursor = null # : string
	) -> ApiGetMessageListResponse:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiGetMessageListResponse.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message"
		var query_params = ""
		if p_limit != null:
			query_params += "limit=%d&" % p_limit
		if p_forward != null:
			query_params += "forward=%s&" % str(bool(p_forward)).to_lower()
		if p_cursor != null:
			query_params += "cursor=%s&" % SatoriSerializer.escape_http(p_cursor)
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiGetMessageListResponse.new(result)
		var out : ApiGetMessageListResponse = SatoriSerializer.deserialize(_namespace, "ApiGetMessageListResponse", result)
		return out

	# Deletes a message for an identity.
	func delete_message_async(
		p_session : SatoriSession
		, p_id : String
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message/{id}"
		urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "DELETE"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# Updates a message for an identity.
	func update_message_async(
		p_session : SatoriSession
		, p_id : String
		, p_body : 
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/message/{id}"
		urlpath = urlpath.replace("{id}", SatoriSerializer.escape_http(p_id))
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()

	# List properties associated with this identity.
	func list_properties_async(
		p_session : SatoriSession
	) -> ApiProperties:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return ApiProperties.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/properties"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "GET"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return ApiProperties.new(result)
		var out : ApiProperties = SatoriSerializer.deserialize(_namespace, "ApiProperties", result)
		return out

	# Update identity properties.
	func update_properties_async(
		p_session : SatoriSession
		, p_body : ApiUpdatePropertiesRequest
	) -> SatoriAsyncResult:
		var try_refresh = await _refresh_session(p_session)
		if try_refresh != null:
			if try_refresh.is_exception():
				return SatoriAsyncResult.new(try_refresh.get_exception())
			await p_session.refresh(try_refresh)
		var urlpath : String = "/v1/properties"
		var query_params = ""
		var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""]
		var method = "PUT"
		var headers = {}
		var header = "Bearer %s" % p_session.token
		headers["Authorization"] = header

		var content : PackedByteArray = PackedByteArray()
		content = JSON.stringify(p_body.serialize()).to_utf8_buffer()

		var result = await _http_adapter.send_async(method, uri, headers, content)
		if result is SatoriException:
			return SatoriAsyncResult.new(result)
		return SatoriAsyncResult.new()
