Audit Log Events Overview
This model is part of an upcoming API update which is currently in beta and therefore subject to change.
Event
An Event represents some action that an actor took, which affected a list of targets.
An Event is an object with the following top-level properties:
| Property | Type | Required | Description |
|---|---|---|---|
actor | object | Required | The entity that performed the action. An object with identifiers and type properties. identifiers is an array of Identifier objects. type must be one of person, system, or external. See Actor. |
action | string | Required | The customer-defined identifier for the action, e.g. assignment.submit. |
targets | object[] | Required | The entities affected by the action. An array of objects, each with an identifiers array of Identifier objects and an Edlink-preferred type property. See Target. |
scope | object | Required | The scope the Event belongs to. An object with id and type, where type is either integration or institution. |
context | object | Strongly Suggested | Information about the underlying network request associated with the event. See Network Context. Every sub-property is optional. |
data | object | Optional | Completely arbitrary data relevant to the Event. Validated only if your Schema defines a data shape. |
schema | object | read-only | This is present when reading the event, to know which version and id of Schema was validating the event. |
created_date | date | read-only | This is present when reading the event, to know when the event was received. |
Identifier
Both actor and each target carry an identifiers array. Each element is an Identifier object with the following properties:
| Property | Type | Required | Description |
|---|---|---|---|
value | string | Required | The identifier value, as a string. |
issuer | string | Required | A label for the system issuing the identifier. The special value "edlink" indicates that the value is an Edlink entity UUID, to be matched against Edlink's data set for automatic enrichment. Any other string is treated as a customer-defined issuer (e.g. "acme", "internal_db"). |
The identifiers array lets you associate multiple identifiers with the same entity when it is known across different systems. When at least one Identifier has an issuer of "edlink", Edlink will look up the referenced entity and enrich it with the matching Edlink model under a details property when the Event is read back.
Target
A Target is an object representing an entity affected by an action. It has two properties:
type: an Edlink-preferred type string (e.g.assignment,class,person). Unrecognized types are accepted as customer-specific data.identifiers: an array of Identifier objects.
Actor
The actor is the entity that performed the action. It has two properties:
type: one of the following enum values:person: a natural person (a human user).system: an automated system or service (e.g. a background job, a cron task, or a service account) acting on its own.external: an outside party acting on the system (e.g. a third-party webhook, a partner integration, or an unauthenticated external request).
identifiers: an array of Identifier objects.
For example:
{
"actor": {
"identifiers": [
{ "value": "00000000-0000-0000-0000-000000000000", "issuer": "edlink" },
{ "value": "acme_user_42", "issuer": "acme" }
],
"type": "person"
}
}
Scope
A scope in an Event refers to the segment of your application which an Event belongs to.
Ideally, this is an Edlink Integration, to allow for the richest data-filling and search capabilities.
Scope is required, because it's how you can list Events for search and review purposes.
However, you might wish to send Events related to other schools or districts you do business with, but are not connected via Edlink.
The institution option is ideal for this, since it references Learning Institutions which Edlink still knows about via our Public Data API.
Network Context
The context object describes the request that produced the Event.
It is not controllable by a Schema.
Edlink only understands the properties enumerated below.
Every property is optional, but the strings will be validated for reasonable formats, like "GET" for http_method or "1.1.1.1" for ip, and a warning will be given on non-compliant data.
| Property | Type | Description |
|---|---|---|
source | enum | client or server are the only valid values. |
user_agent | string | The user agent header from the underlying network request. |
http_method | string | The HTTP method of the request (e.g. POST). |
http_status | number | The HTTP status of the response (e.g. 200). |
path | string | The request path. |
ip | string | The IP address. (Must be a valid CIDR string) |
query | string | The query string of the request. |
hostname | string | Identifier for the computer making the request |
os | string | Name/version string for the computer's operating system |
environment | string | A tag for the environment (e.g. prod or staging) |
trigger | enum | The precipitating action for the event. One of person (triggered by a human user), system (triggered by an automated process), or external (triggered by an outside party). |
deployment_id | string | The identifier for the internal code deployment/version related to this event |
Edlink-preferred Types
Some fields support a type sub-field that is "Edlink-preferred." When you pass an Edlink Data Model type name (such as person or class) as the type, Edlink will automatically match the supplied id to the related Edlink entity. When a match is found, the data is automatically enriched with the full Edlink model.
If you supply a type string that Edlink does not recognize, the data is still accepted — it is simply treated as customer-specific data that cannot be enriched. A common use case is passing your own internal user identifiers for users who log into your platform without using Edlink's SSO.
Note that actor.type does not participate in this Edlink-preferred mechanism — it is constrained to the enum person, system, or external. To enrich an actor with an Edlink entity, include an Identifier with issuer: "edlink" in actor.identifiers.
The list of recognized Edlink types includes:
assignment: Assignment modelclass: Class modelcourse: Course modeldistrict: District modelenrollment: Enrollment modelfile: File modelintegration: Integration modelmodule: Module modelpage: Page modelperson: Person modelresource: Resource modelschool: School modelsession: Session modelsource: Source modelsubmission: Submission model
For example, this target:
{
"targets": [
{
"identifiers": [{ "value": "00000000-0000-0000-0000-000000000000", "issuer": "edlink" }],
"type": "person"
}
]
}
is enriched with the Edlink Person model, which is returned under a details property:
{
"targets": [
{
"identifiers": [{ "value": "00000000-0000-0000-0000-000000000000", "issuer": "edlink" }],
"type": "person",
"details": {
"id": "00000000-0000-0000-0000-000000000000",
"created_date": "2021-07-13T17:45:39.937Z",
"updated_date": "2021-07-13T17:45:39.937Z",
"first_name": "George",
"last_name": "Bluth",
"display_name": "Gob Bluth",
"roles": ["student"],
"email": "gob.bluth@example.com"
}
}
]
}
Similarly, an actor with an Identifier whose issuer is "edlink" will be enriched with the Edlink model that corresponds to its type:
{
"actor": {
"identifiers": [
{ "value": "00000000-0000-0000-0000-000000000000", "issuer": "edlink" }
],
"type": "person",
"details": {
"id": "00000000-0000-0000-0000-000000000000",
"first_name": "George",
"last_name": "Bluth",
"display_name": "Gob Bluth",
"roles": ["student"],
"email": "gob.bluth@example.com"
}
}
}
Default Actions and Schemas
It can be difficult to know what to track.
To facilitate easy adoption of Audit Logs, Edlink pre-defines some common actions with their associated Schemas.
All Schemas are set to lax for flexibility.
Of course, your deep understanding of your own product will let you create new ones, or update these existing actions with Schemas that are more appropriate to your product's needs.
However, we consider these a good starting point for developers:
user.login Schema
{
"version": "00000000-0000-0000-0000-000000000000",
"validation_level": "lax",
"action": {
"id": "user.login",
"type": "create" // "creating" a session
},
"data": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ed.link/api/default-schemas/user.login.json",
"title": "user.login",
"description": "An event describing a user logging into a client's application.",
"type": "object",
"properties": {
"internal_user_id": {
"description": "The unique identifier for a user in the client's application",
"type": "string"
},
"application_name": {
"description": "Name of the application the user is accessing",
"type": "string"
},
"previous_login_date": {
"description": "The timestamp of the user's last login",
"type": "string"
}
},
"required": [ "internal_user_id" ]
}
}
user.logout Schema
{
"version": "00000000-0000-0000-0000-000000000000",
"validation_level": "lax",
"action": {
"id": "user.logout",
"type": "delete" // "deleting" a session
},
"data": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ed.link/api/default-schemas/user.logout.json",
"title": "user.logout",
"description": "An event describing a user logging out of a client's application.",
"type": "object",
"properties": {
"internal_user_id": {
"description": "The unique identifier for a user in the client's application",
"type": "string"
},
"application_name": {
"description": "Name of the application the user is accessing",
"type": "string"
},
"session_duration_ms": {
"description": "The duration of the user's session in milliseconds",
"type": "integer"
}
},
"required": [ "internal_user_id" ]
}
}
content.access Schema
{
"version": "00000000-0000-0000-0000-000000000000",
"validation_level": "lax",
"action": {
"id": "content.access",
"type": "read"
},
"data": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ed.link/api/default-schemas/content.access.json",
"title": "content.access",
"description": "An event describing a user accessing some content within a client's application.",
"type": "object",
"properties": {
"internal_user_id": {
"description": "The unique identifier for a user in the client's application",
"type": "string"
},
"application_name": {
"description": "Name of the application the user is accessing",
"type": "string"
},
"content_name": {
"description": "The human-readable name of the content",
"type": "string"
},
"content_type": {
"description": "The internal type of the content (text, video, etc)",
"type": "string"
}
},
"required": [ "internal_user_id" ]
}
}