Ojs.Api.Client 0.1.0-preview

This is a prerelease version of Ojs.Api.Client.
dotnet add package Ojs.Api.Client --version 0.1.0-preview
                    
NuGet\Install-Package Ojs.Api.Client -Version 0.1.0-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ojs.Api.Client" Version="0.1.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ojs.Api.Client" Version="0.1.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="Ojs.Api.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ojs.Api.Client --version 0.1.0-preview
                    
#r "nuget: Ojs.Api.Client, 0.1.0-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ojs.Api.Client@0.1.0-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ojs.Api.Client&version=0.1.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Ojs.Api.Client&version=0.1.0-preview&prerelease
                    
Install as a Cake Tool

OJS 3.5 .NET Client

A .NET client for the Open Journal Systems 3.5 REST API. It is written in VB.NET and works from any .NET language: VB.NET, C#, F#, PowerShell and others.

  • Complete. It covers every public endpoint of OJS 3.5:
    • submissions, publications, contributors, files, decisions and reviews;
    • issues, sections, users and invitations;
    • journals, site settings, themes, announcements and institutions;
    • email templates, DOIs, ORCID, statistics, vocabularies and RORs.
  • Typed. Models with enums for OJS constants, and multilingual values (LocalizedString, LocalizedVocab). Edit models send only the fields you set.
  • Tested against real servers. The PHP backend's quirks are handled for you: string numbers, "Y-m-d H:i:s" dates, [] for empty objects, responses that differ from the OpenAPI document, and more. See OJS 3.5 Quirks.
  • Convenient. Automatic paging, IAsyncEnumerable streaming, typed exceptions with validation messages, file uploads and downloads, and CSV statistics.
  • No dependencies. It needs only System.Net.Http and System.Text.Json from .NET 10.

Install

dotnet add package Ojs.Api.Client --prerelease

The package contains OJS3_5.Library.dll; all types are in the OJS3_5.Library namespace (OJS3_5.Library.OjsClient, OJS3_5.Library.Models, ...).

Quick start

You need an API token: in OJS, open User Profile > API Key. The server must have api_key_secret set in config.inc.php.

VB.NET

Imports OJS3_5.Library
Imports OJS3_5.Library.Models
Imports OJS3_5.Library.Queries

Using ojs As New OjsClient(New OjsClientOptions With {
    .BaseUrl = "https://journals.example.com",
    .JournalPath = "jpk",
    .ApiToken = Environment.GetEnvironmentVariable("OJS_TOKEN")})

    Dim current = Await ojs.Issues.GetCurrentAsync()
    Console.WriteLine(current.Identification)
    For Each article In current.Articles
        Console.WriteLine("  " & article.CurrentPublication?.Title.GetValue("en"))
    Next
End Using

C#

using OJS3_5.Library;

using var ojs = new OjsClient(new OjsClientOptions
{
    BaseUrl = "https://journals.example.com",
    JournalPath = "jpk",
    ApiToken = Environment.GetEnvironmentVariable("OJS_TOKEN")
});

var current = await ojs.Issues.GetCurrentAsync();
Console.WriteLine(current.Identification);
foreach (var article in current.Articles)
    Console.WriteLine("  " + article.CurrentPublication?.Title.GetValue("en"));

F#

open OJS3_5.Library

task {
    use ojs =
        new OjsClient(OjsClientOptions(
            BaseUrl = "https://journals.example.com",
            JournalPath = "jpk",
            ApiToken = Environment.GetEnvironmentVariable "OJS_TOKEN"))
    let! current = ojs.Issues.GetCurrentAsync()
    printfn "%s" current.Identification
}

If the installation's URLs contain index.php (e.g. https://example.com/index.php/jpk), set UseIndexPhp = True.

Examples

Pagination

' One page
Dim page = Await ojs.Submissions.ListAsync(New SubmissionQuery With {.Status = {SubmissionStatus.Published}, .Count = 50})
Console.WriteLine($"{page.Items.Count} of {page.ItemsMax}")

' Every page
Dim all = Await ojs.Submissions.ListAllAsync(New SubmissionQuery With {.StageIds = {WorkflowStage.ExternalReview}})
// Stream page by page
await foreach (var issue in ojs.Issues.Enumerate(new IssueQuery { IsPublished = true }))
    Console.WriteLine(issue.Identification);

Multilingual metadata and partial updates

Dim pub = Await ojs.Publications.GetAsync(12, 15)
Console.WriteLine(pub.Title.GetValue("id", fallbackLocale:="en"))
Console.WriteLine(String.Join(", ", pub.Keywords.GetNames("en")))

' Only the properties you set are sent; everything else stays as it is.
Await ojs.Publications.UpdateAsync(12, 15, New PublicationEdit With {
    .Title = New LocalizedString From {{"en", "A better title"}, {"id", "Judul yang lebih baik"}},
    .Keywords = LocalizedVocab.Create("en", "open access", "scholarly publishing")})

Uploads

' Images and other settings files: upload, then reference
Dim tmp = Await ojs.TemporaryFiles.UploadAsync("cover.jpg")
Await ojs.Publications.UpdateAsync(12, 15, New PublicationEdit With {
    .CoverImage = New Dictionary(Of String, CoverImage) From {{"en", New CoverImage With {.TemporaryFileId = tmp.Id}}}})

' Submission files
Using pdf = File.OpenRead("manuscript.pdf")
    Await ojs.SubmissionFiles.UploadAsync(12, pdf, "manuscript.pdf",
        New SubmissionFileEdit With {.FileStage = SubmissionFileStage.Submission, .GenreId = 1})
End Using

Errors

try
{
    await ojs.Submissions.SubmitAsync(12, confirmCopyright: true);
}
catch (OjsValidationException ex)
{
    foreach (var (field, messages) in ex.Errors)
        Console.WriteLine($"{field}: {string.Join(" ", messages)}");
}
catch (OjsApiException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
    Console.WriteLine("No such submission.");
}

Several journals

For Each journal In Await ojs.Contexts.ListAllAsync()
    Dim client = ojs.ForJournal(journal.UrlPath)   ' shares the connection
    Console.WriteLine($"{journal.Name.GetValue("en")}: {(Await client.Submissions.ListAsync()).ItemsMax} submissions")
Next

DOIs and statistics

Await ojs.Dois.Submissions.AssignAsync({12, 13})
Using xml = Await ojs.Dois.Submissions.ExportAndDownloadAsync({12, 13})
    Await xml.SaveAsAsync(xml.FileName)
End Using

Dim top = Await ojs.Stats.Publications.ListAsync(New PublicationStatsQuery With {.DateStart = New DateOnly(2026, 1, 1), .Count = 10})
Dim csv = Await ojs.Stats.Publications.ListCountriesCsvAsync()

API overview

OjsClient property Endpoints
Submissions, Publications, Contributors, SubmissionFiles, Decisions, ReviewerSuggestions the editorial workflow
Issues, Sections journal structure
Users, Invitations accounts, roles and reviewers
Contexts, Site journals, site settings and themes
Announcements, Institutions news, and institutions for statistics
EmailTemplates, Mailables, Emails emails
Dois, Reviews, Orcid DOIs, review exports and ORCID
Stats editorial, user and usage statistics
Vocabs, Rors keyword suggestions and the Research Organization Registry
TemporaryFiles uploads referenced by other requests
SendAsync raw access to any endpoint

Documentation

  • Wiki: one page per area, with examples in VB.NET, C# and F#.

  • XML documentation: every public member has a summary and an example, shown in IntelliSense.

  • Sample app: Samples/Library.Sample is a small command-line tool:

    set OJS_BASE_URL=https://journals.example.com
    set OJS_JOURNAL=jpk
    set OJS_TOKEN=...
    dotnet run --project Samples/Library.Sample -- issues
    dotnet run --project Samples/Library.Sample -- submission 12
    dotnet run --project Samples/Library.Sample -- stats
    

Building and testing

dotnet build OJS3_5.slnx
dotnet test OJS3_5.slnx

The unit tests need no server. The live tests run against a real journal when you set the OJS_* environment variables, and the tests that change data also need OJS_ALLOW_WRITES=1. Run those against a test journal only. See Testing and Contributing.

tools/doc-check compiles every code example in the XML documentation and the wiki, in VB.NET, C# and F#.

Compatibility

  • OJS: 3.5.x. Tested against OJS 3.5.0.
  • .NET: .NET 10 or later.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0-preview 0 11/8/2026