Trusted Partner: Accounts Registration API

Last Updated on 3/25/2022

Introduction: Registering Organizations via Accounts API

An organization that has been designated as a trusted partner with authority may use the accounts Organization Register API to add their partner organizations.

Trusted Third Party with Authority workflow is defined as: The trusted third party has authorization to publish for the data organization, without the data organizations having to first create an account and give explicit authorization to the third party.

  1. The trusted organization, such as a state body, registers with the CE accounts site. Under their organization information, they would indicate that they plan to act as a third party publisher.
  2. This organization will likely have already had meetings with the CE team to discuss their plans. A CE team member has to designate an organization as a trusted partner.
  3. The trusted partner is responsible for validation of the organizations for whom they will be publishing.
  4. Typically the trusted partner will use either the accounts API endpoint or a bulk upload in the accounts site to register the organizations for whom they will be publishing.
  5. Both the API endpoint or bulk upload process will:
    • Validate the data
    • At least one contact is required. This person will be added as an administrator for the new organization.
    • The administrator will receive an email requesting confirmation of their account. This administrator can add additional contacts as needed.
    • The organization will be created, approved, and assigned an API key for publishing.
    • A third party relationship will be created and approved for publishing.
    • The provided contact will receive an email as notification that their organization has been added by the trusted partner.

      NOTE: when testing in the sandbox, an organization may not want to send emails to the target organization contacts. The API parameter: SendingOrgContactEmails can be used. If this property is set to false, then no emails will be sent.
      June 2023 This property can now be also used in production.

  6. When publishing the third party organization would use their API key and the CTID for one of the client organizations as the PublishForOrganizationIdentifier parameter when publishing to the registry.
  7. The Assistant API process will validate whether a particular API key can be used to publish data for a particular organization CTID.

Calling the Register Organization Endpoint

Make an HTTP POST to the following API endpoint to register organizations:

https://apps.credentialengine.org/accountsapi/organization/register

Include your organization's API key in the header:

Authorization: ApiToken [YOUR API KEY]

Sample:

using ( var client = new HttpClient() ) { client.DefaultRequestHeaders. Accept.Add( new MediaTypeWithQualityHeaderValue( "application/json" ) ); //Add Authorization header client.DefaultRequestHeaders.Add( "Authorization", "ApiToken " + "YOUR API KEY" ); //........ }

Endpoint Steps

The register endpoint will perform the following steps:

  • Verify caller is a trusted partner (using the API Key)
  • Validate the request
  • If valid, add the organization
  • If the contact doesn’t exist (based on the contact email address), create the user
  • Add the provided contact as an administration user to the organization
  • Approve the organization
  • Set up and approve a third party relationship between the organization and the caller (trusted organization)
  • Send emails to all parties

NOTE: when testing in the sandbox, an organization may not want to send emails to the target organization contacts. The API parameter: SendingOrgContactEmails can be used. If this property is set to false, then no emails will be sent.
June 2023 This property can now be also used in production.

Managing Existing Organizations

There may be cases where an organization for which your organization will be publishing on behalf of, already exists in the accounts site and likely in the Credential Registry. In this case, you can still perform the third party publishing on their behalf for data likely from a different state than other third party publishers.

However there will be a different workflow for this scenario:

  • If an organization exists, the API will return a message along with the CTID for the existing organization in the property: ExistingOrganizationCTID. You must store this CTID in your system (rather than the one you might have originally used when trying to register).
  • You would then repeat the register transaction with the existing provided CTID:
    • You will not be able to update any core data (name, URL, address, etc.) for the organization (this step would be ignored)
    • Any contacts in the register transaction will NOT be added to the target organization
    • The publishing third party relationship will still be set up and approved

Validate Endpoint

Publishing resources:

  • You will NOT be able to publish the organization directly (an error will occur if attempted)
  • The process for publishing other resources would be unchanged.

Input Properties

The following sections list the properties for the input classes.

Organization

Property Data
Required
Input Data
The CTID is essentially a product identifier. Any data such as credentials, organizations, assessments, etc. that is published to the registry must have a CTID.
The CTID for an organization is required to be specified as the owning organization when publishing any data to the registry.
Note:
Databases often have a data type for a UUID. For example, SQL Server uses the data type: uniqueidentifer. So the uniqueidentifier with the prefix of ce- could be used.
Yes
Constraints:
The format is an all-lowercase UUID (Universally Unique Identifier) prefixed with ce-. The UUID is often referred to as a GUID in some program languages.
Example:
ce-c427f875-a123-b456-c789-9c6b9ef2143d
Name
Official name of the organization
Yes
Constraints:
2-200 characters
Description
A description of the organization. Required if any of the following publishing methods are included:
  • ManualEntry
  • BulkUpload
  • CompetencyFrameworks
No
Constraints:
If included, must be a minimum of 25 characters.
Url
URL for the organizations's main website.
Yes
Email
Email address for the organization
Yes
Constraints:
Must be a valid email address
Example:
info@organization.net
PrimaryPhoneNumber
Primary phone number of the organization.
Yes
Constraints:
Must be a valid phone number.
Example:
800-555-1212
PrimaryPhoneExtension
Primary phone number extension.
No
Example:
x123
SecondaryPhoneNumber
Secondary phone number of the organization.
No
Constraints:
Only provided if important. Must be a valid phone number.
Example:
800-555-1213
SecondaryPhoneExtension
Secondary phone number extension.
No
Example:
x456
FEIN
Federal Employer Identification Number
No
DUNS
Data Universal Numbering System number
No
OPEID
Office of Postsecondary Education Identification number
No
ProfileName
Screen name for the organization, comparable to one that would be used for social media.
Note:
If no value is provided, one will be generated with the format: profile_f492597f-9b33-4205-b49c-8f6f09a9c466
No
Constraints:
- 3-50 characters
- Must not already be in use by another organization
Example:
SpringfieldU
OrganizationPublishingRoleUris
Publishing role(s) for the organization.
Note:
While ThirdParty is a valid role in the Accounts System, it is not an allowed option here.
Yes
Constraints:
- List of strings
- Values must be one or more of:
  • CredentialOrganization
  • QACredentialOrganization
  • CompetencyFrameworkOrganization
Example:
CredentialOrganization
OrganizationPublishingMethodUris
Publishing method(s) for the organization
Note:
At least one is Required if a publishing role is selected.
Yes
Constraints:
- List of strings
- Values must be one or more of:
  • RegistryAssistant
  • ManualEntry
  • BulkUpload
  • CompetencyFrameworks

NOTE: if any of the latter three are selected, the organization will be sync'd to the CE Publisher site. Generally, if organization information will only be published to the Credential Registry using the Registry Assistant, then only RegistryAssistant should be selected.

Example:
RegistryAssistant
OrganizationConsumingMethodUris
Consuming method(s) for the organization
No
Constraints:
- List of strings
- Values must be one or more of:
  • CreateWidget
  • SearchApi
  • OfflineStorage
Example:
SearchApi
OrganizationSectorUri
The primary organization sector
Yes
Constraints:
- A single string, select one of:
  • PrivateNonProfit
  • PrivateForProfit
  • Public
Example:
Public
OrganizationTypeUris
Organization Type(s).
Note:

The complete list:

  • Alternative/Non-Traditional School
  • Assessment Body
  • Business or Industry Association
  • Business
  • Career and Technical School 
  • Certification Body 
  • Collaborative
  • Coordinating Body
  • Education and Training Provider 
  • Four-Year College 
  • Government Agency
  • High School
  • Labor Union 
  • Magnet/Competitive Admissions School
  • Military
  • Postsecondary Educational Institution
  • Primarily Online 
  • Professional Association 
  • Quality Assurance Body
  • Secondary School 
  • Two-Year College 
  • Vendor
Yes
Constraints:
List of strings, with one or more organization types. See:
https://credreg.net/ctdl/terms/OrganizationType#OrganizationType
Example:
Education and Training Provider | Four-Year College
StreetAddress
Primary address of the Organization.
Yes
City
City for primary address of the Organization.
Yes
StateProvince
The state/province/region for the primary address of the Organization.
Yes
Country
The country for the primary address of the Organization.
Yes
PostalCode
The postal code for the primary address of the Organization.
Yes
Contacts
Contacts for the organization
Yes
Constraints:
List of Admin Contacts
- At least one contact is required.
SendingOrgContactEmails
Set to false to NOT send emails to organization contacts.
No
Constraints:
June 2023. This property can now also be used in production.

AdminContact

List of Admin Contacts. At least one contact must be included.

If a contact is not known for the target organization, then provide a person from the staff of the requesting organization. All contacts will receive notifications regarding updates to the organization and summary emails when data is published for the organization.

NOTE: If the third party organization will be responsible for managing the data in the accounts site, then always use a contact from the third party.

Property Data
Required
Input Data
Email
Email for a primary contact for the organization.
Yes
Constraints:
Must be a valid email address
Example:
info@organization.net
FirstName
First Name of a primary contact.
Yes
LastName
Last Name of a primary contact.
Yes
DaytimePhoneNumber
Day time phone number of a primary contact.
No
Constraints:
Must be a valid phone number.
Example:
800-555-1212
DaytimePhoneExtension
Day time phone number extension.
No
Example:
x123

PublishingEstimate

Property Data
Required
Input Data
EntityTypeUri
CTDL type URI for the type of entity for this estimate
No
Constraints:
Must be a valid CTDL type URI
Example:
ceterms:Certificate

Response Properties

The following sections list the terms returned by the API Response.

Response

Property Data
Notes
Successful
Indicates whether or not the action was successful.
Messages
List of error messages if Successful = false. Typically there are no messages if successful= true.
OrganizationApiKey
If successful, the apiKey for the new organization is returned. The caller can choose to store it, or pass it on to the organization.
ExistingOrganizationCTID
If the organization being requested already exists, the existing CTID will be returned along with guidance that this CTID must be used in the partner system.

Sample Code

The following sections provide code samples.

Sample API Input

{ "Name": "This Community College", "Description": "Description of This Community College", "Ctid": "ce-xxxxxxxx-1220-001c-xxxx-d45917a407ac", "Url": "https://example.com/yourTest/", "FEIN": "xx-1234567", "PrimaryEmail": "test@test.com", "PrimaryPhoneNumber": "(800) 555-1212", "OrganizationPublishingRoleUris": [ "CredentialOrganization" ], "OrganizationPublishingMethodUris": [ "RegistryAssistant" ], "OrganizationConsumingMethodUris": [ "SearchApi" ], "OrganizationTypeUris": [ "orgType:TwoYear","certificationBody" ], "OrganizationSectorUri": "agentSector:Public", "Contacts": [ { "Email": "test@your.org", "FirstName": "John", "LastName": "AdminUser" } ], "StreetAddress": "1375 S Clare Avenue", "City": "Harrison", "StateProvince": "Michigan", "PostalCode": "48625", }

Sample C# Input Class

public class OrganizationAddition { // Required public string CTID { get; set; } // Required public string Name { get; set; } // Optional unless publishing methods include any of: ManualEntry, BulkUpload, or CompetencyFramework public string Description { get; set; } // Organization Profile name // Max of 50 characters, must be unique to the accounts site // If blank, will be set to default of profile-GUID // IF NOT SURE IT WILL BE UNIQUE - DON'T INCLUDE public string ProfileName { get; set; } // Recommended, but no longer required for registrations by trusted partners public string FEIN { get; set; } public string DUNS { get; set; } public string OPEID { get; set; } // Required Primary URL for the organization public string Url { get; set; } // Required public string PrimaryPhoneNumber { get; set; } public string PrimaryPhoneExtension { get; set; } public string SecondaryPhoneNumber { get; set; } public string SecondaryPhoneExtension { get; set; } public string PrimaryEmail { get; set; } // OrganizationPublishingRoleUris // One or more of // - CredentialOrganization, // - QACredentialOrganization, // - CompetencyFrameworkOrganization // Required public List<string> OrganizationPublishingRoleUris { get; set; } = new List<string>(); // OrganizationPublishingMethodUris // One or more of // - BulkUpload // - CompetencyFrameworks // - ManualEntry // - RegistryAssistant // Required public List<string> OrganizationPublishingMethodUris { get; set; } = new List<string>(); // OrganizationConsumingMethodUris // Zero or more of // - CreateWidget // - OfflineStorage // - SearchApi // Required public List<string> OrganizationConsumingMethodUris { get; set; } = new List<string>(); // OrganizationType concept scheme // See: https://credreg.net/ctdl/terms/OrganizationType#OrganizationType // Required public List<string> OrganizationTypeUris { get; set; } = new List<string>(); // OrganizationSector concept scheme // One of (defaults to Public) // - PrivateNonProfit // - PrivateForProfit // - Public // Required public string OrganizationSectorUri { get; set; } /// <summary> /// If false, do NOT send emails to confirm accounts. /// June 2023 This property can now be also used in production. /// </summary> public bool? SendingOrgContactEmails { get; set; } = true; // List of contacts for this organization // At least one contact is required public List<AdminContact> Contacts { get; set; } = new List<AdminContact>(); // Properties for Address // All required public string StreetAddress { get; set; } public string City { get; set; } public string StateProvince { get; set; } public string Country { get; set; } public string PostalCode { get; set; } // Optional public List<PublishingEstimate> PublishingEstimates { get; set; } = new List<PublishingEstimate>(); } public class PublishingEstimate { public string EntityTypeUri { get; set; } public int EstimatedCount { get; set; } public string Comment { get; set; } } public class AdminContact { public string Email { get; set; } public string LastName { get; set; } public string FirstName { get; set; } public string DaytimePhoneNumber { get; set; } public string DaytimePhoneExtension { get; set; } }

Calling the API - Sample C# Code

The following is sample C# code for calling the API.

// For serialization/deserialization methods using Newtonsoft.Json; public void RegisterOrganization() { string publisherApikey = “provide your api key here”; // URL for sandbox var accountsApiUrl = “https://sandbox.credentialengine.org/accountsAPI/organization/register”; // Provide a valid CTID string ctid = "ce-????????-????-????-????-????????????"; API.OrganizationAddition org = new API.OrganizationAddition() { Name = "Delta College", Url = "http://example.com/DeltaCollege", // Max length = 50. Must be unique. Leave blank to have system set a default. ProfileName = "profile_" + Guid.NewGuid().ToString().ToLowerInvariant(), CTID = ctid, FEIN = "??-nnnnnnn", DUNS = "", OPEID = "" }; // Add a publishing role (with or without the namespace of publishRole) org.OrganizationPublishingRoleUris.Add("publishRole:CredentialOrganization"); // Add one or more publishing methods org.OrganizationPublishingMethodUris.Add("ManualEntry"); org.OrganizationPublishingMethodUris.Add("publishMethod:RegistryAssistant"); // Add one sector org.OrganizationSectorUri = "agentSector:Public"; // Add one or more organization types org.OrganizationTypeUris.Add("orgType:TwoYear" ); org.PrimaryEmail = "test@email.com"; org.PrimaryPhoneNumber = "800-555-1212"; // Add an administrator for the new organization org.Contacts.Add( new AdminContact() { Email = "adminUser@myEmail.org", FirstName = "My", LastName = "Name" } ); org.StreetAddress = "1961 Main Str"; org.City = "Somewhere"; org.StateProvince = "Michigan"; org.PostalCode = "48710"; org.Country = "USA"; // Call accounts API string contents = ""; // Serialize string postBody = JsonConvert.SerializeObject(org, GetJsonSettings()); try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "ApiToken " + publisherApikey); var task = client.PostAsync(accountsApiUrl, new StringContent(postBody, Encoding.UTF8, "application/json")); task.Wait(); var response = task.Result; contents = task.Result.Content.ReadAsStringAsync().Result; // Deserialize to the response object (or could use a Dictionary object); var orr = JsonConvert.DeserializeObject(contents); if (response.IsSuccessStatusCode == false) { // Inspect messages individually or place all in a string var status = string.Join("", orr.Messages.ToArray()); } else { // Check to ensure OK // { // "Successful":true, // "Messages":[], // "OrganizationApiKey":"????????-????-????-????-????????????", // "ApprovedToPublish":true // } } } // End using } catch (Exception ex) { // Handle errors, while very unlikely LoggingHelper.LogError(ex, string.Format(thisClassName + ".TestRegisterOrganization FAILED. Publisher OrgName: {0}, target orgCtid", org.Name, org.CTID)); string message = LoggingHelper.FormatExceptions(ex); } } public static JsonSerializerSettings GetJsonSettings() { var settings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore, Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; return settings; }