Hi RN, I don't know what is the level of risk you're willing to have in this project. Joe has been working on a native Shiny API, but it is under development and it's likely it will still change a lot before we release into the master branch. So, if you need something stable, it may be a while (I can't say exactly how long, but at very least, a few weeks). However, if you just need something quick right now, you can use the implementation that we have today (this is kept in an undocumented branch on Github).
First, you need to install that branch of Shiny:
devtools::install_github("rstudio/shiny@feature/api")
Second, for ease of explanation here, let's also set a particular port to listen for your Shiny app (and make it not pop up every time):
options(shiny.launch.browser = FALSE, shiny.port = 7791)
Then. let's say your app looks like this:
library(shiny)
ui <- fluidPage(
selectInput(inputId = "n_breaks",
label = "Number of bins in histogram (approximate):",
choices = c(10, 20, 35, 50),
selected = 20),
checkboxInput(inputId = "individual_obs",
label = strong("Show individual observations"),
value = FALSE),
plotOutput(outputId = "main_plot", height = "300px")
)
server <- function(input, output, session) {
output$main_plot <- renderPlot({
hist(faithful$eruptions,
probability = TRUE,
breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)",
main = "Geyser eruption duration")
if (input$individual_obs) {
rug(faithful$eruptions)
}
})
}
shinyApp(ui, server)
So, you have two inputs (`
n_breaks` and `
individual_obs`) and one plot output (`
main_plot`). It's pretty basic, it looks like this:

So, let's say you want to make this plot available though a URL, where you can also specify the two inputs that control it (`n_breaks` and `individual_obs`). Simply add this to your server function (notice that the content of the function is exactly the same, it's only the name of the object and the function itself that have changed...):
session$api$main_plot <- servePlot({
hist(faithful$eruptions,
probability = TRUE,
breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)",
main = "Geyser eruption duration")
if (input$individual_obs) {
rug(faithful$eruptions)
}
})

These two URLs are not really related in any way. In fact, each time that you click "enter" on the API URL, Shiny will start up your app, run it once with the params you give it and immediately shut it down, saving only the artifact that you served with the serve function.

Hope this helps you somewhat! Just keep in mind that this is still a very experimental feature that may change quite a bit in the immediate future... If this is enough for you, you can always just make sure you're on the same version of Shiny (same commit SHA), but that's obviously not a scalable answer if your app changes...