Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.


Build status NuGet Badge

stream-net is a .Net client for Stream.

You can sign up for a Stream account at

Installation via Nuget

nuget install stream-net


// Create a client, find your API keys here
var client = new StreamClient("YOUR_API_KEY","API_KEY_SECRET");

// Reference a feed
var userFeed1 = client.Feed("user", "1");

// Get 20 activities starting from activity with id last_id (fast id offset pagination)
var results = await userFeed1.GetActivities(0, 20, FeedFilter.Where().IdLessThan(last_id));

// Get 10 activities starting from the 5th (slow offset pagination)
var results = await userFeed1.GetActivities(5, 10);

// Create a new activity
var activity = new Activity("1", "like", "3")
	ForeignId = "post:42"

// Create a complex activity
var activity = new Activity("1", "run", "1")
	ForeignId = "run:1"
var course = new Dictionary<string,object>();
course["name"] = "Shevlin Park";
course["distance"] = 10;
activity.SetData("course", course);

// Remove an activity by its id

// Remove activities by their foreign_id
userFeed1.RemoveActivity("post:42", true);

// Let user 1 start following user 42's flat feed
userFeed1.FollowFeed("flat", "42");

// Let user 1 stop following user 42's flat feed
userFeed1.UnfollowFeed("flat", "42");

// Delete a feed (and its content)

// Retrieve first 10 followers of a feed
userFeed1.Followers(0, 10);

// Retrieve 2 to 10 followers
userFeed1.Followers(2, 10);

// Retrieve 10 feeds followed by $user_feed_1
userFeed1.Following(0, 10);

// Retrieve 10 feeds followed by $user_feed_1 starting from the 10th (2nd page)
userFeed1.Following(10, 20);

// Check if $user_feed_1 follows specific feeds
userFeed1.Following(0, 2, new String[] { "user:42", "user:43" });

// Follow stats
// Count the number of users following this feed
// Count the number of tags are followed by this feed
var stats = userFeed1.FollowStats(new string []{ "user" }, new string[] { "tags" })

// Retrieve activities by their ids
var ids = new string[] { "e561de8f-00f1-11e4-b400-0cc47a024be0", "a34ndjsh-00f1-11e4-b400-0c9jdnbn0eb0" };
var activities = await client.Batch.GetActivities(ids)

// Retrieve activities by their ForeignID/Time
var foreignIDTimes = new ForeignIDTime[] {new ForeignIDTime("fid-1", DateTime.Parse("2000-08-19T16:32:32")), new Stream.ForeignIDTime("fid-2",  DateTime.Parse("2000-08-21T16:32:32"))};
var activities = await client.Batch.GetActivities(null, foreignIDTimes)

// Partially update an activity
var set = new GenericData();
set.SetData("custom_field", "new value");
var unset = new string[]{"field to remove"};

// by id
await client.ActivityPartialUpdate("e561de8f-00f1-11e4-b400-0cc47a024be0", null, set, unset);

// by foreign id and time
var fidTime = new ForeignIDTime("fid-1", DateTime.Parse("2000-08-19T16:32:32"));
await client.ActivityPartialUpdate(null, fidTime, set, unset);

//add a reaction to an activity
var activityData = new Activity("bob", "cook", "burger")
	ForeignId = "post:42"
var activity = await userFeed1.AddActivity(activity);

var r = await client.Reactions.Add("comment", activity.Id, "john");

// add a reaction to a reaction
var child = await client.Reactions.AddChild(r.ID, "upvote", activity.Id, "john");

// enrich feed results
var userData = new Dictionary<string, object>()
	{"is_admin", true},
var u = await client.Users.Add("timmy", userData);
var userRef = u.Ref();

var a = new Stream.Activity(uRef, "add", "post");
var plainActivity = await userFeed1.AddActivity(a);

// plainActivity.Actor is just a plain string containing the user ref

var enriched = await this._user1.GetEnrichedFlatActivities();
var actor = enriched.Results.First();
if (actor.IsEnriched)
	//The `Enriched` propery contains the user object instead of just the ref
	var userID = actor.Enriched.GetData<string>("id");
	var data = actor.Enriched.GetData<Dictionary<string,object>>("data"); //this is `userData`

// enrich feed results with reactions

var activityData = new Activity("bob", "cook", "burger")
	ForeignId = "post:42"
var activity = await userFeed1.AddActivity(activity);

var com = await client.Reactions.Add("comment", activity.Id, "john");
var like = await client.Reactions.Add("like", activity.Id, "maria");

// fetch reaction counts grouped by reaction kind
var enriched = await this._user1.GetEnrichedFlatActivities(GetOptions.Default.WithReaction(ReactionOption.With().Counts())));

var enrichedActivity = enriched.Results.First();
Console.WriteLine(enrichedActivity.ReactionCounts["like"]); //1
Console.WriteLine(enrichedActivity.ReactionCounts["comment"]); //1

// fetch reactions grouped by reaction kind
var enriched = await this._user1.GetEnrichedFlatActivities(GetOptions.Default.WithReaction(ReactionOption.With().Own())));

var enrichedActivity = enriched.Results.First();
Console.WriteLine(enrichedActivity.OwnReactions["like"]); // is the $like reaction
Console.WriteLine(enrichedActivity.OwnReactions["comment"]); // is the $comment reaction

// all reactions enrichment can be selected
var enriched = await this._user1.GetEnrichedFlatActivities(GetOptions.Default.WithReaction(ReactionOption.With().Counts().Own().Recent()));

// Personalization
var input = new Dictionary<string, object>()
    {"feed_slug", "my_personalized_feed"},
    {"user_id", "john"},
    {"limit", 20},
    {"ranking", "my_ranking"}
var response = await client.Personalization.Get("my_endpoint", input);

// File & Image Uplaod
var fileUpload = await client.Files.Upload(stream, name, contentType);
var imageupload = await client.Images.Upload(stream, name, contentType);
// Use fileUpload.File and imageUpload.File afterwards

// Open graph
Og og = await client.Og("");

Copyright and License Information

Project is licensed under the BSD 3-Clause.


We welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our Contributor License Agreement (CLA) first. See our license file for more details.

Head over to for some development tips.

We are hiring!

We've recently closed a $38 million Series B funding round and we keep actively growing. Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world.

Check out our current openings and apply via Stream's website.